Почему shared_from_this нельзя использовать в конструкторе с технической точки зрения?

В книга Стандартная библиотека С++ на стр. 91 Я прочел это о shared_from_this():

Проблема заключается в том, что shared_ptr хранится в частном члене Person s базовый класс, enable_shared_from_this<>, в концепостроение Человека.

Соответствующий фрагмент кода из книги:

class Person : public std::enable_shared_from_this<Person> {
   ...
};

Я не понимаю здесь двух вещей:

  • кто этот shared_ptr, который хранит себя?
  • как он может хранить себя где-нибудь в конце конструкции Person? Я думаю, что построение Person заканчивается последним утверждением его конструктора, написанным мной.

Я понимаю, что есть weak_ptr, который еще не был инициализирован.

EDIT: Спасибо Angew! shared_from_this будет работать только после создания первого shared_ptr до Person. Этот shared_ptr проверяет, унаследован ли класс Person от enable_shared_from_this, и если да, то инициализируйте его внутренний weak_ptr.

Ответ 1

Причина проста: в объекте X, enable_shared_from_this работает путем инициализации скрытого weak_ptr с копией первого shared_ptr, который указывает на объект X. Однако, чтобы shared_ptr мог указывать на X, X должен уже существовать (он должен быть уже построен). Поэтому, пока выполняется конструктор X, еще нет shared_ptr, который может использовать enable_shared_from_this.

Возьмите этот кусок кода:

std::shared_ptr<Person> p(new Person());

Прежде чем конструктор p (of shared_ptr) будет даже вызываться, его аргумент должен быть оценен. Этот аргумент является выражением new Person(). Поэтому конструктор Person запускается до того, как конструктор p даже начался, прежде чем есть какой-либо объект shared_ptr, с которым может связываться enable_shared_from_this.