enable_shared_from_this - пустой внутренний слабый указатель? - PullRequest
19 голосов
/ 21 декабря 2010

Я использую enable_shared_from_this<Base>, а затем наследую от Base.При попытке использовать shared_from_this() в конструкторе Derived (не в списке инициализатора) я получаю исключение.Оказывается, что внутренний слабый указатель нулевой и совсем не указывает на this.Как это может случиться?Мой другой вариант использования именно этого прекрасно работает.Я даже не знаю с чего начать.Я посмотрел на исходный код enable_shared_from_this, и мне кажется, что указатель всегда будет nullptr.

Ответы [ 3 ]

37 голосов
/ 21 декабря 2010

Вы не можете вызвать shared_from_this() в конструкторе объекта. shared_from_this() требует, чтобы объект принадлежал как минимум одному shared_ptr. Объект не может принадлежать shared_ptr до его создания.

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

5 голосов
/ 21 декабря 2010

Ответ Джеймса Макнеллиса правильный.

Что касается объяснения самого шаблона 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 в качестве открытого базового класса.

1 голос
/ 09 октября 2011

Концептуально shared_from_this() выбирает shared_ptr, указывающий на this, и возвращает его копию.

В конструкторе нет shared_ptr, указывающего на this.

...