В C++ я использую boost::shared_ptr
и boost::weak_ptr
автоматически удалить объекты, которые больше не необходимы. Я знаю, что они работают с подсчетом ссылок.
В Java памятью управляет сборщик "мусора", который рассматривает встроенные ссылки на объект как сильные, WeakReference
как слабый и SoftReference
как что-то промежуточное (может быть собран GC, но может также пережить GC), который действительно удобен для кэширования объектов в течение некоторого времени, но выбрасывание их, как только свободная память понижается.
Таким образом, теперь я вернулся в C++, и я пропускаю комфорт наличия мягких ссылок. Интересно, реальна ли мягкая ссылка с подсчетом ссылок вообще. Когда последняя сильная ссылка к объекту очищена и там остается мягкой ссылкой, когда она была бы удалена, в конце концов? Я мог думать о некоторых схемах, но ни один из них не кажется умным мне.
На всякий случай существует надлежащая семантика для мягких ссылок наряду с подсчетом ссылок, интересно, было ли это уже реализовано, возможно, способом это даже совместимо с boost::shared_ptr
(или эквивалентный TR1 C++ std::shared_ptr
в этом отношении).
Если ответ на оба вопроса не, каковы альтернативы в сценарии кэширования объекта?
Править: Конечно, я говорю о ситуации, когда кэширование на самом деле полезно, потому что объекты являются дорогостоящими для построения (думайте о нескольких доступах к базе данных и запросам сети), все же существуют слишком многие для хранения их всех навсегда.
Вы можете реализовать собственный кэш LRU и новый smart_pointer, связанный с таким кэшем. Я не думаю, что такая структура существует в Boost или стандартном C++ (во всяком случае, мне так кажется). Если вы делаете веб-приложение или что-то подобное... вы можете использовать libmemcached, который является C-интерфейсом для memcached.
Мне трудно представить ситуацию, в которой такой объект будет настолько дорого создавать/уничтожать... в то время как повторная инициализация будет дешевой... что кэш LRU станет полезным. Но если он вам действительно нужен, у вас есть инструменты для его создания.
Как указывали другие, вы можете найти ссылочные счетные указатели (и их сопутствующие слабые аналоги ) в библиотеке Boost, но что В идее мягкой ссылки отсутствует некоторая осведомленность об ограничениях памяти среды выполнения. В Java, например, SoftReference
существенно не отличается от WeakReference
по своим возможностям; скорее, это контракт о том, как среда выполнения сохранит или исключит два вида ссылок перед лицом нехватки памяти, которая отличается.
Чтобы имитировать это поведение в C ++, вам необходимо создать кэш ссылок с учетом памяти, который будет содержать сильных ссылок на объекты, которые остальная часть вашего приложения будет удерживать слабо ]. Когда кеш определил, что приложение исчерпало свой потолок использования памяти - или любые другие ограничивающие критерии - он освободил сильные ссылки, сдавая объекты для «сбора» (достигнув нулевого счетчика ссылок) и разрешив использование слабых ссылок позже. обнаружить недействительность.
Если вы действительно хотите воспроизвести это поведение, вы можете использовать сборщик мусора (например: http://www.hpl.hp.com/personal/Hans_Boehm/gc/ ) и используйте его для ухода за своим объектом или их подмножеством, где использование SoftReferences было бы полезно.
Но я бы предпочел найти решение, более родное для C ++, чем репликация поведения Java, но ничто не мешает вам сделать это.
Нет, в C ++ такого нет. И быть не должно. Каждый объект служит важной цели. Если этого не произошло, то почему он у вас до сих пор? Хранение объектов таким образом - утечка памяти. Если вам нужен объект, он вам нужен. Если вы этого не сделаете, уничтожьте его. Между полезным и бесполезным нет ничего промежуточного, либо оно служит цели, либо нет.
Если вы в отчаянии, вполне возможно написать собственный сборщик мусора и реализовать его самостоятельно. Но я бы рекомендовал не нуждаться в них или использовать их вообще.
Изменить: при кэшировании объектов люди обычно используют кеши LRU. При промахе кеша ссылка на объект, который не использовался недавно, удаляется (если кеш заполнен), новый объект создается и помещается как последний использованный, а все остальные перемещаются вниз. Однако обычно вам нужно получить элементы с диска, прежде чем вам действительно понадобится стратегия кэширования в C ++. Стоимость создания большинства объектов просто не так велика.