Так, я использую повышение:: shared_ptr для всех различных преимуществ подсчета ссылок это обеспечивает - подсчет ссылок для начинающих, очевидно, но также и способность скопировать, присвоить, и поэтому сохранить в Контейнерах STL.
Проблема, если я передаю ее всего одной "злонамеренной" функции или объекту, объект может сохранить ptr, и затем я никогда не буду мочь освободить ее без внешней функции или объекта, приятно оставляющего его владение.
В конечном счете я пытаюсь сохранить монопольное использование объекта явным. Я выполняю, это при наличии владельца сохраняет единственный shared_ptr к объекту, и "гость" возражает только хранилищу weak_ptrs к объекту.
Я действительно не хочу "общую" часть shared_ptr, но я обязан использовать shared_ptr для создания weak_ptrs. Я хочу использовать scoped_ptr, но он чрезвычайно ограничен, так как Вы не можете скопировать его. Вы не можете сохранить его в контейнере, Вы не можете выдать weak_ptrs от него, и Вы не можете передать владение новому менеджеру.
Каково решение?
Достаточно хорошо использовать weak_ptr для гостевых объектов, как вы описали в вопросе. В противном случае у вас будет проблема с мертвыми указателями.
Я бы подумал о том, чтобы изменить архитектуру приложения, чтобы удалить «вредоносные» функции / объекты или, по крайней мере, исправить их поведение.
Если вы хотите обрабатывать свои объекты в этой парадигме «владелец / владелец», я рекомендую сделать что-нибудь вроде Qt.
setOwner (Object * owner)
, чтобы установить владельца, и убедитесь, что этот метод уведомляет объект-владелец о новом дочернем элементе. На что следует обратить внимание:
Вы можете расширить класс повышения shared_ptr и переопределить delete, чтобы принудительно удалить указатель.
Проблема на самом деле в том, что если библиотека не выпускает или не освобождает shared_ptr, то она, вероятно, когда-нибудь обратится к нему. В это время ваше приложение получит сообщение SIGSEGV.
Я считаю, что это полностью сводит на нет цель общих указателей.
Лучшее решение - исправить библиотеку.
Другое решение: использовать АОП для удаления указателя при выходе из библиотечной функции, которую вы вызываете. Это все еще может сломаться.
Сделайте его приватным и предоставьте фасад для выполнения любых необходимых операций. Указателя никто никогда не видит. Я предполагаю, что на этом этапе вам даже не понадобится shared_ptr.
Не передавать объект boost :: shared_ptr ... даже если вы храните объект внутри, используя boost :: shared_ptr, вы должны убедиться, что функции принимают ваш объект по постоянной ссылке, а не по копии общего указателя. Поскольку вам нужно будет разыменовать общий указатель, чтобы передать объект функции, которая передает по ссылке const, вы будете знать, следует ли он этому протоколу или нет.
На самом деле нет хорошего решения для того, что вы описываете.
Вы не можете использовать auto_ptr, потому что вы не передаете право собственности.
Если вы можете гарантировать, что владелец переживет ссылки, я бы рекомендовал использовать scoped_ptr / store по значению в владельце, а затем передавать необработанный указатель или ссылку тем, кто в нем нуждается.
Если ссылки могут пережить владельца (и ссылки должны быть аккуратно уведомлены), вы должны использовать shared_ptr / weak_ptr. Но, как вы заявили, вы не можете предотвратить блокировку weak_ptr каким-либо классом / функцией и «предотвращение» освобождения. Но в интерфейсе не передавайте shared_ptr, передавайте weak_ptr. Он настолько силен, насколько условен, но он говорит: «Не цепляйтесь за это, это может уйти».