Есть несколько вопросов, которые касаются поведения std::enable_shared_from_this
, но я не думаю, что это дубликат.
Классы, которые наследуются от std::enable_shared_from_this
, содержат std::weak_ptr
член. Когда приложение создает std::shared_ptr
, указывающий на подкласс std::enable_shared_from_this
, конструктор std::shared_ptr
проверяет std::weak_ptr
и, если он не инициализирован, инициализирует его и использует блок управления std::weak_ptr
для std::shared_ptr
, Однако, если std::weak_ptr
уже инициализирован, конструктор просто создает новый std::shared_ptr
с новым блоком управления. Это приводит к сбою приложения, когда счетчик ссылок одного из двух экземпляров std::shared_ptr
обнуляется и удаляет базовый объект.
struct C : std::enable_shared_from_this<C> {};
C *p = new C();
std::shared_ptr<C> p1(p);
// Okay, p1 and p2 both have ref count = 2
std::shared_ptr<C> p2 = p->shared_from_this();
// Bad: p3 has ref count 1, and C will be deleted twice
std::shared_ptr<C> p3(p);
Мой вопрос: почему библиотека ведет себя так? Если конструктор std::shared_ptr
знает, что объект является подклассом std::enable_shared_from_this
и пытается проверить поле std::weak_ptr
, почему он не всегда использует один и тот же блок управления для нового std::shared_ptr
, что позволяет избежать потенциального сбоя?
И в этом отношении, почему метод shared_from_this
терпит неудачу, когда элемент std::weak_ptr
не инициализируется, вместо того, чтобы просто инициализировать его и вернуть std::shared_ptr
?
Кажется странным, что библиотека работает так, как она работает, так как она терпит неудачу в ситуациях, когда она может легко преуспеть. Мне интересно, были ли конструктивные соображения / ограничения, которые я не понимаю.
Я использую Clang 8.0.0 в режиме C ++ 17.