std::enable_shared_from_this
定义在头文件 <memory> 中 |
||
template< class T > class enable_shared_from_this; |
(自 C++11 起) | |
std::enable_shared_from_this
允许一个当前由名为 pt
的 std::shared_ptr 管理的对象 t
安全地生成额外的 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
的所有权。
内容 |
[编辑] 成员函数
构造一个 enable_shared_from_this 对象(受保护的成员函数) | |
销毁一个 enable_shared_from_this 对象(受保护的成员函数) | |
返回对 *this 的引用 (受保护的成员函数) | |
返回一个 std::shared_ptr,该对象共享 *this 的所有权 (公共成员函数) | |
(C++17) |
返回一个 std::weak_ptr,该对象共享 *this 的所有权 (公共成员函数) |
[编辑] 成员对象
成员名称 | 定义 |
weak-this (private) |
std::weak_ptr 对象跟踪 *this 的第一个共享所有者的控制块。 (仅供说明*) |
[编辑] 注释
enable_shared_from_this
的一种常见实现是持有对 *this 的弱引用(例如 std::weak_ptr)。为了说明,弱引用被称为 weak-this
,并且被认为是可变的 std::weak_ptr 成员。
当构造 std::shared_ptr 时,会检测是否存在明确且可访问的(即必须为公有继承)enable_shared_from_this
基类,如果未被活动 std::shared_ptr 拥有,则将新创建的 std::shared_ptr 分配给 weak-this
。对于已经被其他 std::shared_ptr 管理的对象,构造 std::shared_ptr 将不会访问 weak-this
,因此会导致未定义的行为。
仅允许在先前共享的对象(即由 std::shared_ptr<T> 管理的对象)上调用 shared_from_this
。否则,将抛出 std::bad_weak_ptr(由从默认构造的 weak-this
创建的 shared_ptr
构造函数抛出)。
enable_shared_from_this
提供了类似 std::shared_ptr<T>(this) 表达式的安全替代方案,该表达式可能会导致多个彼此不知情的拥有者多次销毁 this(请参阅下面的示例)。
[edit] 示例
#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 can't 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's 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
[edit] 缺陷报告
以下行为改变的缺陷报告被追溯应用于之前发布的 C++ 标准。
DR | 应用于 | 发布的行为 | 正确行为 |
---|---|---|---|
LWG 2529 | C++11 | enable_shared_from_this 的规范不明确,可能无法实现 |
已澄清并修复 |
[edit] 另请参阅
(C++11) |
具有共享对象所有权语义的智能指针 (类模板) |
创建一个管理新对象的共享指针 (函数模板) |