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
的所有权。
目录 |
数据成员
| 成员 | 描述 |
mutable
std::
weak_ptr
<
T
>
weak_this
|
跟踪
*
this
首个共享所有者控制块的对象
( 仅用于说明的成员对象* ) |
成员函数
构造
enable_shared_from_this
对象
(受保护成员函数) |
|
销毁
enable_shared_from_this
对象
(受保护成员函数) |
|
|
返回对
*
this
的引用
(受保护成员函数) |
|
|
返回共享
*
this
所有权的
std::shared_ptr
(公开成员函数) |
|
|
(C++17)
|
返回共享
*
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
,这将导致未定义行为。
仅允许在先前已被共享的对象上调用
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: // 构造函数仅限此类内部使用 Best(Private) {} // 其他所有用户必须使用此工厂函数 // 因此所有Best对象都将包含在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() { // 良好实践:两个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() { // 错误实践:在没有std::shared_ptr拥有调用者的情况下调用shared_from_this 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() called Bad::~Bad() called *** 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)
|
具有共享对象所有权语义的智能指针
(类模板) |
|
创建管理新对象的共享指针
(函数模板) |