std::enable_shared_from_this

来自cppreference.com
< cpp‎ | memory
 
 
内存管理库
(仅用于阐述*)
分配器
未初始化内存算法
受约束的未初始化内存算法
内存资源
未初始化存储(C++20 前)
(C++17 弃用)
(C++17 弃用)
垃圾收集器支持(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
 
 
在标头 <memory> 定义
template<class T >
class enable_shared_from_this;
(C++11 起)

std::enable_shared_from_this 能让它的一个已被 std::shared_ptr 类型对象 pt 管理的对象 t 安全地生成其他额外的 std::shared_ptr 实例 pt1pt2 等等,它们都与 pt 共享对象 t 的所有权。

如果类 T 公开继承了 std::enable_shared_from_this<T>,那么就会为该类 T 提供成员函数 shared_from_this。 当 T 类型对象 tstd::shared_ptr<T> 类对象 pt 管理时,调用 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 的引用
(受保护成员函数)
返回共享 *this 所有权的 std::shared_ptr
(公开成员函数)
返回共享 *this 所有权的 std::weak_ptr
(公开成员函数)

[编辑]注解

std::shared_ptr 的构造函数会检测无歧义且可访问的 enable_shared_from_this 基类(即强制公开继承),并且在 weak_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 异常(通过 std::shared_ptr 的构造函数,来源为默认构造的 weak_this )。

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:// 只有自己可以使用构造函数 Best(Private){}   // 其他地方都必须使用此工厂函数// 因此所有 Best 对象均将被 shared_ptr 容纳staticstd::shared_ptr<Best> create(){returnstd::make_shared<Best>(Private());}   std::shared_ptr<Best> getptr(){return shared_from_this();}};   struct Bad {std::shared_ptr<Bad> getptr(){returnstd::shared_ptr<Bad>(this);} ~Bad(){std::cout<<"调用 Bad::~Bad()\n";}};   void testGood(){// 好:两个 shared_ptr 共享同一对象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(){// 坏:调用 shared_from_this 但没有 std::shared_ptr 占有调用者try{ Good not_so_good;std::shared_ptr<Good> gp1 = not_so_good.getptr();}catch(std::bad_weak_ptr& e){// 未定义行为(C++17 前)/ 抛出 std::bad_weak_ptr(C++17 起)std::cout<< e.what()<<'\n';}}   void testBest(){// 最好:同上但无法栈分配它: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; // <- 不会通过编译,因为 Best::Best() 为私有。}   void testBad(){// 不好,每个 shared_ptr 都认为它是对象的唯一所有者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';}// 未定义行为:Bad 的二次删除   int main(){ testGood(); misuseGood();   testBest();   testBad();}

可能的输出:

good1.use_count() = 2 bad_weak_ptr best1.use_count() = 2 bad1.use_count() = 1 调用 Bad::~Bad() 调用 Bad::~Bad() *** glibc detected *** ./test: double free or corruption

[编辑]缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 出版时的行为 正确行为
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)
拥有共享对象所有权语义的智能指针
(类模板)[编辑]
创建管理一个新对象的共享指针
(函数模板)[编辑]
close