我的类从多个基类继承,其中之一是std::enable_shared_from_this
。它必须是第一个基类吗?
假设下面的示例代码:
struct A { ~A(); };
struct B { ~B(); };
struct C : A, B, std::enable_shared_from_this<C> {};
std::make_shared<C>();
当
~A()
和 ~B()
运行时,我能确信存储 C
所在的空间仍然存在吗?我的类从多个基类继承,其中之一是std::enable_shared_from_this
。它必须是第一个基类吗?
假设下面的示例代码:
struct A { ~A(); };
struct B { ~B(); };
struct C : A, B, std::enable_shared_from_this<C> {};
std::make_shared<C>();
~A()
和 ~B()
运行时,我能确信存储 C
所在的空间仍然存在吗?enable_shared_from_this
可以出现在基类列表的任何位置,实现需要在整个对象销毁后释放内存,无论它如何继承自enable_shared_from_this
”,或者“它必须是第一个基类,在其他任何地方继承都是UB”,或者“此行为未指定或实现质量不佳”。 - Filipp~A()
和~B()
时,我可以确定C
所在的存储空间仍然存在吗?shared_ptr<T>
被销毁或重置时,共享所有权的T
的引用计数(RC)会递减(原子性);如果在递减中达到0,则开始销毁/删除T
。T
不再存在:我们需要知道是否还有其他对控制块感兴趣的实体;如果递减结果非零,则表示某些weak_ptr
存在,它们共享(可以是1份或100%)控制块的所有权,并且现在负责释放内存。C
期间,最后一个weak_ptr<T>
也已经被销毁。(您问题中未写明的假设是没有其他weak_ptr<T>
被保留。)shared_ptr<T>
知道(通常情况下)调用哪个(潜在的非虚拟)最终派生类的析构函数。(控制块还知道不要在make_shared
的共享计数达到零时释放内存。)weak_ptr
,使用 make_shared
创建出来的对象的 weak_count
为1。释放 shared_ptr
会先将 use_count
减1。如果变成了0,则销毁对象(但不会销毁控制块)。然后 weak_count
减1,如果变成了0,则销毁并释放控制块。继承自 enable_shared_from_this
的对象的 weak_count
起始值为2。这正是 STL 实现者所期望的卓越解决方案。 - Filipprandom_access_iterator_tag
)。有非正式协议称与容器相关的任何内容都是 STL 的一部分。简而言之:标准库中并非所有模板都属于 STL,也并非所有非模板都在其范围之外。 - curiousguyenable_shared_from_this
不是第一个基类,shared_ptr
、weak_ptr
和enable_shared_from_this
的实现是否需要保留足够长的时间来确保这是安全的。 - Filippenable_shared_from_this
,使其更安全。 - Filipp
enable_shared_from_this
必须是一个可访问的明确的基类。在我的例子中,它是的。C
是一个结构体。它公开继承。 - Filipp~weak_ptr();
作用: 销毁此weak_ptr
对象,但不会影响存储指针所指向的对象。” 强调是我的。 - Igor Tandetnikshared_ptr
消失时,存储对象的生命周期也随之结束。即使weak_ptr
保留了控制块以防止其被释放,我认为这并不重要。 - HolyBlackCatC
的生命周期已经结束,因为最后一个共享的shared_ptr<T>
已经被销毁(或重置)。问题在于当在T
对象销毁开始时仍有剩余的weak_ptr<T>
时如何处理资源。 - curiousguy