Как я могу обнаружить или избежать циклических ссылок с std :: shared_ptr? - PullRequest
3 голосов
/ 22 февраля 2012

Я знаю, что есть weak_ptr, чтобы разорвать цикл, но это исправление после обнаружения проблемы.Есть ли шаблон или инструмент, который можно использовать для обнаружения или предотвращения циклических ссылок?

Ответы [ 4 ]

4 голосов
/ 22 февраля 2012

Вы избегаете этого по замыслу.Как замечательно отметил Стефан Т. Лававей на конференции GoingNative2012 (вы можете посмотреть видео онлайн), «владение» - это ориентированный ациклический граф, DAG.В DAG нет циклов.Если ваш график владения не DAG, ваш дизайн… сомнителен, потому что A, владеющий B и B, владеющий A, не имеет смысла.Но shared_ptr - это «указатель общего владения».Объект или область видимости, содержащая такой указатель, являются владельцем объекта.Попытайтесь думать с точки зрения графиков собственности.

shared_ptr не является подходящим инструментом для каждого случая.Он не должен позволять вам кодировать так же, как вы делаете это, скажем, в Java, где вам не нужно много думать о владении.Предполагается обеспечить автоматическую и детерминированную очистку.Если вам нужен указатель «не владеющий», то будет уместен слабый указатель или необработанный указатель.Просто убедитесь, что объект, на который указывает необработанный указатель, остается живым достаточно долго.

2 голосов
/ 22 февраля 2012

Очевидный ответ - не использовать shared_ptr для объектов, которые сами могут содержать shared_ptr. shared_ptr несколько особенный, и должен использоваться экономно.

1 голос
/ 22 февраля 2012

Я бы полностью повторил сказанное Sellibitze и переосмыслил дизайн. Если то, что у вас действительно есть, является односторонним владением и просто наблюдением в противоположном направлении, рассмотрите слабый_птр. Это позволяет вам проверить, является ли объект живым, но не поддерживает его, просто потому что у вас есть указатель на него.

0 голосов
/ 22 февраля 2012

Вы можете реализовать один, что-то вроде оболочки над smart_ptr, которая при создании хранит указатель this (например, макросом).Затем построите ориентированный граф с ребрами из сохраненного this объекта, содержащегося в shared_ptr, и определите любые циклы, например, путем топологической сортировки.

Я бы рекомендовал это только для большой базы кода с интенсивным использованием shared_ptr инеспособность контролировать все аспекты дизайна.Для других случаев просто используйте рекомендацию @sellibitze.

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