std::enable_shared_from_this
定义于头文件 <memory> |
||
template< class T > class enable_shared_from_this; |
(自 C++11 起) | |
std::enable_shared_from_this
允许对象 t(当前由名为 pt 的 std::shared_ptr 管理)安全地生成额外的 std::shared_ptr 实例 pt1、pt2 等,所有这些实例都与 pt 共享 t 的所有权。
公开继承自 std::enable_shared_from_this<T>
为类型 T
提供了成员函数 shared_from_this
。如果类型为 T
的对象 t 由名为 pt 的 std::shared_ptr<T> 管理,则调用 T::shared_from_this
将返回一个新的 std::shared_ptr<T>,它与 pt 共享 t 的所有权。
目录 |
[编辑] 数据成员
成员 | 描述 |
mutable std::weak_ptr<T> weak_this |
跟踪 *this 的首个共享所有者的控制块的对象 (仅为解释目的的成员对象*) |
[编辑] 成员函数
构造一个 enable_shared_from_this 对象(受保护的成员函数) | |
销毁一个 enable_shared_from_this 对象(受保护的成员函数) | |
返回对 *this 的引用 (受保护的成员函数) | |
返回一个 std::shared_ptr,它共享 *this 的所有权 (公共成员函数) | |
(C++17) |
返回一个 std::weak_ptr,它共享 *this 的所有权 (公共成员函数) |
[编辑] 注解
std::shared_ptr 的构造函数检测是否存在明确且可访问的(即,强制要求公共继承)enable_shared_from_this
基类,并将新创建的 std::shared_ptr 赋值给 weak_this
,如果它尚未被活动的 std::shared_ptr 拥有。为已由另一个 std::shared_ptr 管理的对象构造 std::shared_ptr 将不会查询 weak_this
,因此将导致未定义的行为。
仅允许在先前共享的对象上调用 shared_from_this
,即由 std::shared_ptr<T> 管理的对象。否则,将抛出 std::bad_weak_ptr(由从默认构造的 weak_this
构造的 std::shared_ptr 构造函数抛出)。
enable_shared_from_this
提供了表达式(如 std::shared_ptr<T>(this))的安全替代方案,后者很可能导致 this 被多个互不知晓的所有者多次析构(见下例)。
[编辑] 示例
#include <iostream> #include <memory> class Good : public std::enable_shared_from_this<Good> { public: std::shared_ptr<Good> getptr() { return shared_from_this(); } }; class Best : public std::enable_shared_from_this<Best> { struct Private{ explicit Private() = default; }; public: // Constructor is only usable by this class Best(Private) {} // Everyone else has to use this factory function // Hence all Best objects will be contained in shared_ptr static std::shared_ptr<Best> create() { return std::make_shared<Best>(Private()); } std::shared_ptr<Best> getptr() { return shared_from_this(); } }; struct Bad { std::shared_ptr<Bad> getptr() { return std::shared_ptr<Bad>(this); } ~Bad() { std::cout << "Bad::~Bad() called\n"; } }; void testGood() { // Good: the two shared_ptr's share the same object std::shared_ptr<Good> good0 = std::make_shared<Good>(); std::shared_ptr<Good> good1 = good0->getptr(); std::cout << "good1.use_count() = " << good1.use_count() << '\n'; } void misuseGood() { // Bad: shared_from_this is called without having std::shared_ptr owning the caller try { Good not_so_good; std::shared_ptr<Good> gp1 = not_so_good.getptr(); } catch (std::bad_weak_ptr& e) { // undefined behavior (until C++17) and std::bad_weak_ptr thrown (since C++17) std::cout << e.what() << '\n'; } } void testBest() { // Best: Same but cannot stack-allocate it: std::shared_ptr<Best> best0 = Best::create(); std::shared_ptr<Best> best1 = best0->getptr(); std::cout << "best1.use_count() = " << best1.use_count() << '\n'; // Best stackBest; // <- Will not compile because Best::Best() is private. } void testBad() { // Bad, each shared_ptr thinks it is the only owner of the object std::shared_ptr<Bad> bad0 = std::make_shared<Bad>(); std::shared_ptr<Bad> bad1 = bad0->getptr(); std::cout << "bad1.use_count() = " << bad1.use_count() << '\n'; } // UB: double-delete of Bad int main() { testGood(); misuseGood(); testBest(); testBad(); }
可能的输出
good1.use_count() = 2 bad_weak_ptr best1.use_count() = 2 bad1.use_count() = 1 Bad::~Bad() called Bad::~Bad() called *** glibc detected *** ./test: double free or corruption
[编辑] 缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。
DR | 应用于 | 已发布行为 | 正确行为 |
---|---|---|---|
LWG 2179 (P0033R1) |
C++11 | 给定从 enable_shared_from_this 派生的类型 T ,以下行为:从同一个 T* 对象构造两个 std::shared_ptr<T> 的行为不明确 |
在这种情况下,行为是 未定义的 |
LWG 2529 (P0033R1) |
C++11 | 不清楚底层的 std::weak_ptr 如何更新 | 已明确 |
[编辑] 参见
(C++11) |
具有共享对象所有权语义的智能指针 (类模板) |
创建管理新对象的共享指针 (函数模板) |