увеличить shared_from_this <> () - PullRequest
       23

увеличить shared_from_this <> ()

14 голосов
/ 02 сентября 2010

мог бы кто-то кратко описать, как следует использовать интеллектуальный указатель boost shared_from_this<>(), особенно с точки зрения регистрации обработчиков в io_service с использованием функции bind.

РЕДАКТИРОВАТЬ: Некоторые ответы попросили больше контекста. По сути, я ищу «недочеты», нелогичное поведение, которое люди наблюдали, используя этот механизм.

Ответы [ 4 ]

31 голосов
/ 03 сентября 2010

Самая большая «ошибка», с которой я столкнулся, это то, что запрещено вызывать shared_from_this из конструктора.Это напрямую следует из правила, что shared_ptr для объекта должен существовать, прежде чем вы сможете вызвать shared_from_this.

14 голосов
/ 02 сентября 2010

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

Проблема в том, что если ваш класс просто имеет shared_ptr<> для себя в качестве переменной-члена, он никогда не будет автоматически уничтожен, поскольку всегда существует «одна последняя ссылка», свисающая с себя. Наследование от enable_shared_from_this дает вашему классу автоматический метод, который не только возвращает shared_ptr, но и содержит слабый общий указатель в качестве переменной-члена, чтобы не влиять на счетчик ссылок. Таким образом, ваш класс будет освобожден как обычно, когда последняя ссылка на него исчезнет.

Я никогда не использовал его, но это мое понимание того, как оно работает.

8 голосов
/ 02 сентября 2010

shared_from_this<> используется, если объект хочет получить доступ к shared_ptr<>, указывающему на себя.

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

shared_from_this<> можно использовать для решения этой проблемы. Например:

struct A : boost::enable_shared_from_this<A> {
   server *io;
   // ...

   void register_self() {
      io->add_client(shared_from_this());
   }
};
5 голосов
/ 02 сентября 2010

документация boost::asio::io_service деструктор объясняет это довольно хорошо

Описанная выше последовательность уничтожения позволяет программам упростить управление своими ресурсами с помощью shared_ptr <>.Если время жизни объекта привязано к времени жизни соединения (или некоторой другой последовательности асинхронных операций), shared_ptr объекта будет привязан к обработчикам для всех асинхронных операций, связанных с ним.Это работает следующим образом:

  • Когда заканчивается одно соединение, все связанные асинхронные операции завершаются.Соответствующие объекты-обработчики уничтожаются, а все ссылки на объекты shared_ptr уничтожаются.
  • Чтобы завершить работу всей программы, вызывается функция stop () io_service, которая завершает любые вызовы run () как можно скорее.Деструктор io_service, определенный выше, уничтожает все обработчики, вызывая уничтожение всех ссылок shared_ptr на все объекты подключения.

Обычно ваши объекты будут связывать асинхронные операции, где обработчики связаны с функциями-членами, используя boost::bind и boost::shared_from_this().Есть примеров , которые используют эту концепцию.

...