在C++中,对象内部获取自身shared_ptr时应继承enable_shared_from_this并使用shared_from_this(),避免直接new this或构造新shared_ptr,以防引用计数紊乱导致重复释放;需确保对象已被shared_ptr管理,且不在构造或析构函数中调用。

在C++中,当你已经拥有一个被 std::shared_ptr 管理的对象时,如果该对象内部需要获取指向自身的 std::shared_ptr,直接使用
std::shared_ptr是不安全的,会导致多个独立的引用计数,从而引发重复释放或未定义行为。(this)
正确的做法是使用 std::enable_shared_from_this 模板类来安全地获取指向自身的 shared_ptr。
基本用法
要让一个类支持获取自身的 shared_ptr,需要:
- 继承 std::enable_shared_from_this
- 使用 shared_from_this() 成员函数获取
std::shared_ptr
#include#include class MyClass : public std::enable_shared_from_this { public: MyClass() = default; // 安全地返回指向自身的 shared_ptr std::shared_ptr get_shared() { return shared_from_this(); } void do_something() { std::cout << "Doing something...\n"; } }; int main() { auto ptr = std::make_shared (); auto self_ptr = ptr->get_shared(); // 正确方式 self_ptr->do_something(); return 0; }
为什么不能直接 new this?
如果在成员函数中写:
立即学习“C++免费学习笔记(深入)”;
std::shared_ptrbad_ptr(new MyClass(*this)); // 错误!
这会创建一个新的对象和新的引用计数,与原来的 shared_ptr 无关。更危险的是:
std::shared_ptrp1(this); // 千万别这么干!
这会让两个独立的 shared_ptr 管理同一块内存,析构时会重复释放。
注意事项
使用 shared_from_this() 有几个关键点:
- 对象必须已经被一个 shared_ptr 管理,否则调用 shared_from_this() 会抛出 std::bad_weak_ptr 异常
- 不能在构造函数中调用 shared_from_this(),因为此时对象尚未被 shared_ptr 完全接管
- 析构函数中也不建议调用,因为引用计数可能已为零
MyClass() {
auto p = shared_from_this(); // 未定义行为或抛异常
}
线程安全与继承
enable_shared_from_this 内部使用一个 std::weak_ptr 来跟踪对象的生命周期,确保引用计数一致。它支持多线程环境下的安全访问(只要不同时修改同一个 weak_ptr)。
支持多重继承,但要确保 shared_ptr 指向的是继承了 enable_shared_from_this 的那个实例。
基本上就这些。只要记住:想在对象内部返回自己的 shared_ptr,就用 enable_shared_from_this,别自己 new this。










