有几个问题涵盖了 的行为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
字段,为什么它不总是为 new 使用相同的控制块std::shared_ptr
,从而避免潜在的崩溃?
就此而言,为什么该方法在成员未初始化shared_from_this
时会失败,而不是仅仅初始化它并返回 a ?std::weak_ptr
std::shared_ptr
图书馆的工作方式似乎很奇怪,因为它在很容易成功的情况下失败了。我想知道是否有我不理解的设计注意事项/限制。
我在 C++17 模式下使用 Clang 8.0.0。