Как препятствовать тому, чтобы кто-либо крал мой shared_ptr?

Так, я использую повышение:: shared_ptr для всех различных преимуществ подсчета ссылок это обеспечивает - подсчет ссылок для начинающих, очевидно, но также и способность скопировать, присвоить, и поэтому сохранить в Контейнерах STL.

Проблема, если я передаю ее всего одной "злонамеренной" функции или объекту, объект может сохранить ptr, и затем я никогда не буду мочь освободить ее без внешней функции или объекта, приятно оставляющего его владение.

В конечном счете я пытаюсь сохранить монопольное использование объекта явным. Я выполняю, это при наличии владельца сохраняет единственный shared_ptr к объекту, и "гость" возражает только хранилищу weak_ptrs к объекту.

Я действительно не хочу "общую" часть shared_ptr, но я обязан использовать shared_ptr для создания weak_ptrs. Я хочу использовать scoped_ptr, но он чрезвычайно ограничен, так как Вы не можете скопировать его. Вы не можете сохранить его в контейнере, Вы не можете выдать weak_ptrs от него, и Вы не можете передать владение новому менеджеру.

Каково решение?

7
задан Kyle 22 April 2010 в 14:17
поделиться

6 ответов

Достаточно хорошо использовать weak_ptr для гостевых объектов, как вы описали в вопросе. В противном случае у вас будет проблема с мертвыми указателями.

Я бы подумал о том, чтобы изменить архитектуру приложения, чтобы удалить «вредоносные» функции / объекты или, по крайней мере, исправить их поведение.

1
ответ дан 6 December 2019 в 14:02
поделиться

Если вы хотите обрабатывать свои объекты в этой парадигме «владелец / владелец», я рекомендую сделать что-нибудь вроде Qt.

  1. Создайте объект базового класса, от которого будут унаследованы все классы в вашей системе. Каждый объект отслеживает своих родителей / владельцев и детей.
  2. Используйте метод setOwner (Object * owner) , чтобы установить владельца, и убедитесь, что этот метод уведомляет объект-владелец о новом дочернем элементе.
  3. Деструктор Object должен удалить все дочерние объекты при его уничтожении.
  4. Определите шаблонный класс, который определяет интеллектуальный указатель на подкласс Object. Сделайте так, чтобы объект уведомлял любые подключенные интеллектуальные указатели о своем уничтожении, чтобы их значения становились NULL при уничтожении объекта.

На что следует обратить внимание:

  1. Все объекты должны быть выделены с помощью new, чтобы деструктор объектов правильно освободил их.
  2. Если вы забудете установить родительский объект для объекта, произойдет утечка.
  3. Обработка объектов, которые не наследуются от Object, сложно, хотя это можно сделать, определив класс шаблона, который наследуется от Object для хранения их.
0
ответ дан 6 December 2019 в 14:02
поделиться

Вы можете расширить класс повышения shared_ptr и переопределить delete, чтобы принудительно удалить указатель.

Проблема на самом деле в том, что если библиотека не выпускает или не освобождает shared_ptr, то она, вероятно, когда-нибудь обратится к нему. В это время ваше приложение получит сообщение SIGSEGV.

Я считаю, что это полностью сводит на нет цель общих указателей.

Лучшее решение - исправить библиотеку.

Другое решение: использовать АОП для удаления указателя при выходе из библиотечной функции, которую вы вызываете. Это все еще может сломаться.

0
ответ дан 6 December 2019 в 14:02
поделиться

Сделайте его приватным и предоставьте фасад для выполнения любых необходимых операций. Указателя никто никогда не видит. Я предполагаю, что на этом этапе вам даже не понадобится shared_ptr.

10
ответ дан 6 December 2019 в 14:02
поделиться

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

4
ответ дан 6 December 2019 в 14:02
поделиться

На самом деле нет хорошего решения для того, что вы описываете.

Вы не можете использовать auto_ptr, потому что вы не передаете право собственности.

Если вы можете гарантировать, что владелец переживет ссылки, я бы рекомендовал использовать scoped_ptr / store по значению в владельце, а затем передавать необработанный указатель или ссылку тем, кто в нем нуждается.

Если ссылки могут пережить владельца (и ссылки должны быть аккуратно уведомлены), вы должны использовать shared_ptr / weak_ptr. Но, как вы заявили, вы не можете предотвратить блокировку weak_ptr каким-либо классом / функцией и «предотвращение» освобождения. Но в интерфейсе не передавайте shared_ptr, передавайте weak_ptr. Он настолько силен, насколько условен, но он говорит: «Не цепляйтесь за это, это может уйти».

0
ответ дан 6 December 2019 в 14:02
поделиться
Другие вопросы по тегам:

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