C++ std::enable_shared_from_this<T>的作用
std::enable_shared_from_this<T> 是 C++ 标准库中的一个模板类,用于解决一个特定问题:当一个对象本身已被 std::shared_ptr 管理时,如何在该对象的方法内部安全地获取指向自身的 std::shared_ptr。
核心作用
提供安全的 shared_from_this() 方法,返回一个与现有 shared_ptr 共享所有权的智能指针,避免创建额外的控制块。
不使用时的问题:双重控制块(Undefined Behavior)
当对象已被 shared_ptr 管理时,如果在成员函数中直接用 this 创建新 shared_ptr,会生成独立的控制块。这导致:
- 多个控制块独立管理同一对象
- 引用计数不共享
- 对象会被多次释放(双重释放)
错误示例代码
#include <memory>
#include <iostream>
class UnsafeClass {
public:
void process() {
// 危险!创建独立控制块的新 shared_ptr
auto self = std::shared_ptr<UnsafeClass>(this);
std::cout << "Use count: " << self.use_count() << "\n"; // 输出 1(错误!)
}
};
int main() {
auto ptr = std::make_shared<UnsafeClass>();
ptr->process(); // 此时有两个控制块管理同一对象
// 程序结束时会双重释放,导致崩溃!
}
输出示例:
Use count: 1
free(): double free detected in tcache 2 // 崩溃!
使用 enable_shared_from_this 的正确方式
通过继承 enable_shared_from_this<T> 并调用 shared_from_this() 获取安全的共享指针。
正确示例代码
#include <memory>
#include <iostream>
class SafeClass : public std::enable_shared_from_this<SafeClass> {
public:
void process() {
// 安全获取共享指针(共享控制块)
auto self = shared_from_this();
std::cout << "Use count: " << self.use_count() << "\n"; // 输出 2(正确)
}
};
int main() {
auto ptr = std::make_shared<SafeClass>(); // 必须先由 shared_ptr 管理对象
ptr->process(); // 安全:共享同一控制块
// 程序正常退出
}
输出:
Use count: 2
关键规则
-
必须公有继承
class T : public enable_shared_from_this<T> -
对象必须已被
shared_ptr管理
调用shared_from_this()前需存在管理该对象的shared_ptr,否则抛出std::bad_weak_ptr -
禁止在构造/析构中调用
构造时控制块未就绪,析构时控制块已销毁
典型应用场景
class Server : public std::enable_shared_from_this<Server> {
public:
void start() {
// 将自身传递给异步回调(安全共享所有权)
async_task([self = shared_from_this()] {
self->handle_request();
});
}
void handle_request() { /* ... */ }
};
总结:
- 不用 → 多控制块 → 双重释放 → 未定义行为
- 正确使用 → 共享控制块 → 安全生命周期管理
始终通过shared_from_this()获取成员函数中的自引用智能指针。
浙公网安备 33010602011771号