2010-09-02 2 views
13

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

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

+1

Что именно вы не понимаете? Трудно ответить на неориентированный вопрос. – GManNickG

+0

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

ответ

30

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

+4

+1 хороший совет, как правило, я предоставляю свой конструктор и предоставляю статический метод 'shared_ptr create'. –

+2

Я думаю, вы имели в виду, что вы делаете свой конструктор частным. –

14

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

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

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

8

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

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

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

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

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

+0

Ответы, наконец, объяснили мне примеры asio ... В частности, что происходит, если в соединении есть ошибка и пример http-сервера из asio. – Coyote21

Смежные вопросы