C++接口实现场景下如何获取当前实例的shared_ptr并传入MyClass2构造
解决方案
核心是通过C++标准库的std::enable_shared_from_this工具获取指向当前实例的合法共享智能指针,避免手动传递this导致的双重释放问题,且不需要修改DoSomething的方法签名,具体修改逻辑如下:
步骤1:修改MyClass的继承关系
让MyClass公开继承std::enable_shared_from_this<MyClass>,这一步是为了让类的成员函数可以调用shared_from_this()方法,获取指向自身、和外部共享所有权的std::shared_ptr实例。
步骤2:修改DoSomething方法的内部实现
将DoSomething中构造MyClass2的逻辑改为调用第二个带参数的构造函数,传入shared_from_this()的返回值即可。
修改后的完整可运行代码
#include <Windows.h> #include <iostream> #include <memory> // 新增头文件,用于智能指针和enable_shared_from_this相关接口 class MyClass; class MyClass2 { public: std::shared_ptr<MyClass> ptr; MyClass2() { ptr = nullptr; } MyClass2(std::shared_ptr<MyClass> ptrParam) { ptr = std::move(ptrParam); } }; // 公开继承enable_shared_from_this class MyClass : public std::enable_shared_from_this<MyClass> { public: int value; MyClass() : value{1} { OutputDebugString(L"MyClass\r\n"); } ~MyClass() { OutputDebugString(L"~MyClass\r\n"); } std::shared_ptr<MyClass2> DoSomething() { // 调用shared_from_this获取指向当前实例的智能指针,传入MyClass2的构造函数 return std::make_shared<MyClass2>(shared_from_this()); } }; int main() { auto ptr = std::make_shared<MyClass>(); auto ptr2 = ptr->DoSomething(); }
注意事项
- 必须保证
MyClass实例始终由std::shared_ptr持有后再调用DoSomething,否则调用shared_from_this()会触发未定义行为,本示例中main函数使用std::make_shared创建实例完全符合要求。 - 对
std::enable_shared_from_this的继承必须是公开继承,否则shared_from_this()无法正常访问类内部的引用计数控制块信息。 - 该方式获取的智能指针和外部持有的
ptr共享同一个引用计数控制块,不会产生独立的指针副本,也不会出现双重释放的问题。
内容的提问来源于stack exchange,提问作者Marcus
相关产品推荐
相关产品推荐

