文章目录
- 一.解决场景
- 代码示例
- 原因
- 二.解决办法
- 代码
- 三.底层原理
一.解决场景
一个share_ptr管理的类,如果从类的函数里返回类对象(this指针),导致share_ptr引用计数错误,析构时异常问题
代码示例
#include <memory>
#include <iostream>
class Bad
{
public:
std::shared_ptr<Bad> getptr() {
return std::shared_ptr<Bad>(this);
}
~Bad() { std::cout << "Bad::~Bad() called" << std::endl; }
};
int main()
{
// 错误的示例,每个shared_ptr都认为自己是对象仅有的所有者
std::shared_ptr<Bad> bp1(new Bad());
std::shared_ptr<Bad> bp2 = bp1->getptr();
// 打印bp1和bp2的引用计数
std::cout << "bp1.use_count() = " << bp1.use_count() << std::endl;
std::cout << "bp2.use_count() = " << bp2.use_count() << std::endl;
} // Bad 对象将会被删除两次
原因
2个非共享的share_ptr指向同一个对象,未增加引用计数导对象被析构两次
二.解决办法
继承 std::enable_shared_from_this ,则会为该类 T 提供成员函数: shared_from_this 。 当 T 类型对象 t 被一个为名为 pt 的 std::shared_ptr 类对象管理时,调用 T::shared_from_this 成员函数,将会返回一个新的 std::shared_ptr 对象,它与 pt 共享 t 的所有权。
代码
#include <memory>
#include <iostream>
struct Good : std::enable_shared_from_this<Good> // 注意:继承
{
public:
std::shared_ptr<Good> getptr() {
return shared_from_this();
}
~Good() { std::cout << "Good::~Good() called" << std::endl; }
};
int main()
{
// 大括号用于限制作用域,这样智能指针就能在system("pause")之前析构
{
std::shared_ptr<Good> gp1(new Good());
std::shared_ptr<Good> gp2 = gp1->getptr();
// 打印gp1和gp2的引用计数
std::cout << "gp1.use_count() = " << gp1.use_count() << std::endl;
std::cout << "gp2.use_count() = " << gp2.use_count() << std::endl;
}
system("pause");
}
三.底层原理
通过继承enable_shared_from_this,然后调用share_from_this(),返回父类enable_shared_from_this的指针,然后shared_ptr在构造是检查是否可以将其转化来判断是否继承enable_shared_from_this
// 定义 enable_shared_from_this 模板类
template <typename T>
class enable_shared_from_this {
public:
std::shared_ptr<T> shared_from_this() {
return weak_this_.lock(); // 使用 weak_ptr 创建 shared_ptr
}
protected:
// 构造函数,默认初始化 weak_this_
enable_shared_from_this() {}
private:
std::weak_ptr<T> weak_this_; // 用于存储对象的 weak_ptr
// 允许 shared_ptr 访问私有成员
template <typename U>
friend class std::shared_ptr;
};
// 自定义 shared_ptr 的构造函数
template <typename T>
class shared_ptr {
public:
shared_ptr(T* ptr) : ptr_(ptr) {
// 检查对象是否继承自 enable_shared_from_this
if (auto enable_shared = dynamic_cast<enable_shared_from_this<T>*>(ptr)) {
enable_shared->weak_this_ = *this; // 初始化 weak_this_
}
}
// 其他 shared_ptr 成员函数...
private:
T* ptr_; // 实际管理的对象指针
};
// 示例类继承 enable_shared_from_this
class MyClass : public enable_shared_from_this<MyClass> {
public:
void func() {
std::shared_ptr<MyClass> self = shared_from_this(); // 获取指向自身的 shared_ptr
// 使用 self 进行操作...
}
};
// 使用示例
int main() {
std::shared_ptr<MyClass> obj = std::make_shared<MyClass>();
obj->func(); // 正确使用 shared_from_this()
return 0;
}