Я использую enable_shared_from_this<Base>
, а затем наследую от Base
. При попытке использовать shared_from_this()
в конструкторе Derived
(не в списке инициализаторов) я получаю исключение. Оказывается, внутренний слабый указатель равен нулю и вообще не указывает на this
. Как такое могло случиться? Мой другой вариант использования именно этого работает отлично. Я даже не знаю, с чего начать. Я посмотрел на исходный код enable_shared_from_this
, и мне кажется, что этот указатель всегда будет nullptr.
enable_shared_from_this - пустой внутренний слабый указатель?
Ответы (3)
Вы не можете вызвать shared_from_this()
в конструкторе объекта. shared_from_this()
требует, чтобы объект принадлежал хотя бы одному shared_ptr
. Объект не может принадлежать shared_ptr
до его создания.
Я предполагаю, что внутренний слабый указатель устанавливается, когда shared_ptr
впервые становится владельцем объекта. До этого момента не существовало структуры счетчика ссылок, на которую мог бы ссылаться слабый указатель.
Ответ Джеймса МакНеллиса правильный.
Что касается объяснения самого шаблона enable_shared_from_this
, который, как вы заметили, кажется, ничего не делает, обратите внимание на примечание 7 внизу этого страница объясняет:
... шаблон
enable_shared_from_this
содержитweak_ptr
объект, указывающий на производный объект. Однако возникает проблема курицы и яйца: как инициализировать этотweak_ptr
объект, когда нет соответствующегоshared_ptr
объекта. Уловка реализации состоит в том, что конструкторы дляshared_ptr
знают оenable_shared_from_this
и устанавливают объектweak_ptr
во время создания объектаshared_ptr
, которому принадлежит ресурс, имеющийenable_shared_from_this
в качестве общедоступного базового класса.
По сути, shared_from_this()
выбирает shared_ptr
, указывающий на this
, и возвращает его копию.
В конструкторе нет shared_ptr
, указывающего на this
.