Мягкий (нет: слабый), ссылки в C++ - действительно ли это возможно? Существует ли реализация?

В C++ я использую boost::shared_ptr и boost::weak_ptr автоматически удалить объекты, которые больше не необходимы. Я знаю, что они работают с подсчетом ссылок.

В Java памятью управляет сборщик "мусора", который рассматривает встроенные ссылки на объект как сильные, WeakReference как слабый и SoftReference как что-то промежуточное (может быть собран GC, но может также пережить GC), который действительно удобен для кэширования объектов в течение некоторого времени, но выбрасывание их, как только свободная память понижается.

Таким образом, теперь я вернулся в C++, и я пропускаю комфорт наличия мягких ссылок. Интересно, реальна ли мягкая ссылка с подсчетом ссылок вообще. Когда последняя сильная ссылка к объекту очищена и там остается мягкой ссылкой, когда она была бы удалена, в конце концов? Я мог думать о некоторых схемах, но ни один из них не кажется умным мне.

На всякий случай существует надлежащая семантика для мягких ссылок наряду с подсчетом ссылок, интересно, было ли это уже реализовано, возможно, способом это даже совместимо с boost::shared_ptr (или эквивалентный TR1 C++ std::shared_ptr в этом отношении).

Если ответ на оба вопроса не, каковы альтернативы в сценарии кэширования объекта?

Править: Конечно, я говорю о ситуации, когда кэширование на самом деле полезно, потому что объекты являются дорогостоящими для построения (думайте о нескольких доступах к базе данных и запросам сети), все же существуют слишком многие для хранения их всех навсегда.

6
задан Lena Schimmel 4 July 2010 в 15:16
поделиться

4 ответа

Вы можете реализовать собственный кэш LRU и новый smart_pointer, связанный с таким кэшем. Я не думаю, что такая структура существует в Boost или стандартном C++ (во всяком случае, мне так кажется). Если вы делаете веб-приложение или что-то подобное... вы можете использовать libmemcached, который является C-интерфейсом для memcached.

Мне трудно представить ситуацию, в которой такой объект будет настолько дорого создавать/уничтожать... в то время как повторная инициализация будет дешевой... что кэш LRU станет полезным. Но если он вам действительно нужен, у вас есть инструменты для его создания.

1
ответ дан 16 December 2019 в 21:34
поделиться

Как указывали другие, вы можете найти ссылочные счетные указатели (и их сопутствующие слабые аналоги ) в библиотеке Boost, но что В идее мягкой ссылки отсутствует некоторая осведомленность об ограничениях памяти среды выполнения. В Java, например, SoftReference существенно не отличается от WeakReference по своим возможностям; скорее, это контракт о том, как среда выполнения сохранит или исключит два вида ссылок перед лицом нехватки памяти, которая отличается.

Чтобы имитировать это поведение в C ++, вам необходимо создать кэш ссылок с учетом памяти, который будет содержать сильных ссылок на объекты, которые остальная часть вашего приложения будет удерживать слабо ]. Когда кеш определил, что приложение исчерпало свой потолок использования памяти - или любые другие ограничивающие критерии - он освободил сильные ссылки, сдавая объекты для «сбора» (достигнув нулевого счетчика ссылок) и разрешив использование слабых ссылок позже. обнаружить недействительность.

7
ответ дан 16 December 2019 в 21:34
поделиться

Если вы действительно хотите воспроизвести это поведение, вы можете использовать сборщик мусора (например: http://www.hpl.hp.com/personal/Hans_Boehm/gc/ ) и используйте его для ухода за своим объектом или их подмножеством, где использование SoftReferences было бы полезно.

Но я бы предпочел найти решение, более родное для C ++, чем репликация поведения Java, но ничто не мешает вам сделать это.

2
ответ дан 16 December 2019 в 21:34
поделиться

Нет, в C ++ такого нет. И быть не должно. Каждый объект служит важной цели. Если этого не произошло, то почему он у вас до сих пор? Хранение объектов таким образом - утечка памяти. Если вам нужен объект, он вам нужен. Если вы этого не сделаете, уничтожьте его. Между полезным и бесполезным нет ничего промежуточного, либо оно служит цели, либо нет.

Если вы в отчаянии, вполне возможно написать собственный сборщик мусора и реализовать его самостоятельно. Но я бы рекомендовал не нуждаться в них или использовать их вообще.

Изменить: при кэшировании объектов люди обычно используют кеши LRU. При промахе кеша ссылка на объект, который не использовался недавно, удаляется (если кеш заполнен), новый объект создается и помещается как последний использованный, а все остальные перемещаются вниз. Однако обычно вам нужно получить элементы с диска, прежде чем вам действительно понадобится стратегия кэширования в C ++. Стоимость создания большинства объектов просто не так велика.

-2
ответ дан 16 December 2019 в 21:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: