跳到主要内容

std::enable_shared_from_this

定义于头文件 <memory>

自 C++11 起
template< class T > class enable_shared_from_this;

std::enable_shared_from_this 允许一个当前由名为 ptstd::shared_ptr 管理的对象 t 安全地生成其他 std::shared_ptr 实例 pt1, pt2, ... 这些实例都与 pt 共享对 t 的所有权。

公开继承自 std::enable_shared_from_this<T> 为类型 T 提供了一个成员函数 shared_from_this。如果类型为 T 的对象 t 由名为 ptstd::shared_ptr<T> 管理,那么调用 T::shared_from_this 将返回一个新的 std::shared_ptr<T>,它与 pt 共享对 t 的所有权。

成员函数

public(构造函数)构造一个 enable_shared_from_this 对象
(受保护的成员函数)
public(析构函数)销毁一个 enable_shared_from_this 对象
(受保护的成员函数)
publicoperator=返回对 *this 的引用
(受保护的成员函数)
publicshared_from_this返回一个共享 *this 所有权的 shared_ptr
(公共成员函数)
publicweak_from_this(C++17)返回共享 *this 所有权的 weak_ptr
(公共成员函数)

成员对象

publicweak_this (private)(C++17)跟踪 *this 的第一个共享所有者控制块的 std::weak_ptr 对象。
仅用于说明

备注

enable_shared_from_this 的一种常见实现是持有对 this 的弱引用(例如 std::weak_ptr)。

std::shared_ptr 的构造函数会检测是否存在一个明确且可访问的(即必须是公开继承) (自 C++17 起) enable_shared_from_this 基类,并将新创建的 std::shared_ptr 赋给内部存储的弱引用(自 C++17 起,如果尚未被活动的 std::shared_ptr 所拥有)。对于一个已被另一个 std::shared_ptr 管理的对象构造 std::shared_ptr 将不会查找内部存储的弱引用,因此会导致未定义行为。

只允许在先前已共享的对象上调用 shared_from_this,即在由 std::shared_ptr<T> 管理的对象上调用。否则行为是未定义的(直到 C++17)std::bad_weak_ptr 被抛出(由从默认构造的 weak_this 的 std::shared_ptr 构造函数)(自 C++17 起)

enable_shared_from_this 提供了一种安全的替代方案,用于替代像 std::shared_ptr<T>(this) 这样的表达式,该表达式很可能导致 this 被多个互不了解的所有者重复析构(请参见下面的示例)。

特性测试宏标准注释
__cpp_lib_enable_shared_from_this201603L(C++17)std::enable_shared_from_this 的更精确规范

示例

#include <memory>
#include <iostream>

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>
{
public:
std::shared_ptr<Best> getptr() {
return shared_from_this();
}
// No public constructor, only a factory function,
// so there's no way to have getptr return nullptr.
[[nodiscard]] static std::shared_ptr<Best> create() {
// Not using std::make_shared<Best> because the c'tor is private.
return std::shared_ptr<Best>(new Best());
}
private:
Best() = default;
};


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

std::enable_shared_from_this

定义于头文件 <memory>

自 C++11 起
template< class T > class enable_shared_from_this;

std::enable_shared_from_this 允许一个当前由名为 ptstd::shared_ptr 管理的对象 t 安全地生成其他 std::shared_ptr 实例 pt1, pt2, ... 这些实例都与 pt 共享对 t 的所有权。

公开继承自 std::enable_shared_from_this<T> 为类型 T 提供了一个成员函数 shared_from_this。如果类型为 T 的对象 t 由名为 ptstd::shared_ptr<T> 管理,那么调用 T::shared_from_this 将返回一个新的 std::shared_ptr<T>,它与 pt 共享对 t 的所有权。

成员函数

public(构造函数)构造一个 enable_shared_from_this 对象
(受保护的成员函数)
public(析构函数)销毁一个 enable_shared_from_this 对象
(受保护的成员函数)
publicoperator=返回对 *this 的引用
(受保护的成员函数)
publicshared_from_this返回一个共享 *this 所有权的 shared_ptr
(公共成员函数)
publicweak_from_this(C++17)返回共享 *this 所有权的 weak_ptr
(公共成员函数)

成员对象

publicweak_this (private)(C++17)跟踪 *this 的第一个共享所有者控制块的 std::weak_ptr 对象。
仅用于说明

备注

enable_shared_from_this 的一种常见实现是持有对 this 的弱引用(例如 std::weak_ptr)。

std::shared_ptr 的构造函数会检测是否存在一个明确且可访问的(即必须是公开继承) (自 C++17 起) enable_shared_from_this 基类,并将新创建的 std::shared_ptr 赋给内部存储的弱引用(自 C++17 起,如果尚未被活动的 std::shared_ptr 所拥有)。对于一个已被另一个 std::shared_ptr 管理的对象构造 std::shared_ptr 将不会查找内部存储的弱引用,因此会导致未定义行为。

只允许在先前已共享的对象上调用 shared_from_this,即在由 std::shared_ptr<T> 管理的对象上调用。否则行为是未定义的(直到 C++17)std::bad_weak_ptr 被抛出(由从默认构造的 weak_this 的 std::shared_ptr 构造函数)(自 C++17 起)

enable_shared_from_this 提供了一种安全的替代方案,用于替代像 std::shared_ptr<T>(this) 这样的表达式,该表达式很可能导致 this 被多个互不了解的所有者重复析构(请参见下面的示例)。

特性测试宏标准注释
__cpp_lib_enable_shared_from_this201603L(C++17)std::enable_shared_from_this 的更精确规范

示例

#include <memory>
#include <iostream>

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>
{
public:
std::shared_ptr<Best> getptr() {
return shared_from_this();
}
// No public constructor, only a factory function,
// so there's no way to have getptr return nullptr.
[[nodiscard]] static std::shared_ptr<Best> create() {
// Not using std::make_shared<Best> because the c'tor is private.
return std::shared_ptr<Best>(new Best());
}
private:
Best() = default;
};


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