C++ 中的 enable_shared_from_this 详解
enable_shared_from_this 是 C++ 标准库中的一个模板类,用于解决在类的成员函数中需要获取指向自身的 shared_ptr 的问题。
基本概念
当一个对象由 shared_ptr 管理时,如果你想在对象的成员函数中获得一个指向自身的 shared_ptr,直接使用 this 创建新的 shared_ptr 会导致多个不相关的 shared_ptr 管理同一个对象,从而造成重复释放的问题。
enable_shared_from_this 提供了安全的解决方案。
基本用法
#include <memory>
#include <iostream>
class MyClass : public std::enable_shared_from_this<MyClass> {
public:
std::shared_ptr<MyClass> getShared() {
return shared_from_this(); // 安全地获取 shared_ptr
}
void doSomething() {
std::cout << "Doing something..." << std::endl;
}
};
int main() {
std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
// 安全地获取 shared_ptr
std::shared_ptr<MyClass> ptr2 = ptr1->getShared();
std::cout << "ptr1 use_count: " << ptr1.use_count() << std::endl; // 输出 2
std::cout << "ptr2 use_count: " << ptr2.use_count() << std::endl; // 输出 2
ptr2->doSomething();
return 0;
}
使用注意事项
-
必须在对象已被 shared_ptr 管理时使用:
// 错误用法 - 对象未被 shared_ptr 管理 MyClass obj; auto ptr = obj.shared_from_this(); // 抛出 std::bad_weak_ptr 异常 -
不能在构造函数中使用:
class MyClass : public std::enable_shared_from_this<MyClass> { public: MyClass() { // 错误 - 此时对象还未被 shared_ptr 管理 auto ptr = shared_from_this(); // 会抛出异常 } }; -
不能在析构函数中使用:
class MyClass : public std::enable_shared_from_this<MyClass> { public: ~MyClass() { // 错误 - 此时 shared_ptr 引用计数可能已经为 0 auto ptr = shared_from_this(); // 未定义行为 } };
实际应用场景
-
异步回调中保持对象存活:
class NetworkService : public std::enable_shared_from_this<NetworkService> { public: void startAsyncOperation() { auto self = shared_from_this(); asyncOperation([self]() { // 回调中 self 保持对象存活 self->onOperationComplete(); }); } void onOperationComplete() { std::cout << "Operation completed" << std::endl; } }; -
链式调用:
class Builder : public std::enable_shared_from_this<Builder> { public: std::shared_ptr<Builder> step1() { // 执行步骤1 return shared_from_this(); } std::shared_ptr<Builder> step2() { // 执行步骤2 return shared_from_this(); } }; // 使用 auto builder = std::make_shared<Builder>(); builder->step1()->step2();
实现原理
enable_shared_from_this 内部维护了一个 weak_ptr,当对象被 shared_ptr 管理时,shared_ptr 的构造函数会检测对象是否继承自 enable_shared_from_this,如果是,则初始化内部的 weak_ptr。
shared_from_this() 实际上是通过这个 weak_ptr 来创建一个新的 shared_ptr。
线程安全性
shared_from_this() 是线程安全的,但前提是对象的生命周期管理(即所有相关的 shared_ptr 操作)也是线程安全的。
替代方案
如果你不能或不想继承 enable_shared_from_this,可以考虑以下替代方案:
-
传递 shared_ptr 作为参数:
void MyClass::memberFunction(std::shared_ptr<MyClass> self) { // 使用 self } -
使用 weak_ptr 成员变量:
class MyClass { std::weak_ptr<MyClass> weak_this; public: void setSelf(const std::shared_ptr<MyClass>& self) { weak_this = self; } std::shared_ptr<MyClass> getShared() { return weak_this.lock(); } };
enable_shared_from_this 是一个强大的工具,但需要正确使用以避免潜在的问题。

400

被折叠的 条评论
为什么被折叠?



