Namespaces
Variants

std:: enable_shared_from_this

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
定义于头文件 <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
(公开成员函数)
返回共享 * 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)
具有共享对象所有权语义的智能指针
(类模板)
创建管理新对象的共享指针
(函数模板)