C++中enable_shared_from_this()的使用
·
enable_shared_from_this的功能
enable_shared_from_this 是 C++11 定义在头文件 include 中的一个模板类,其作用是在类的内部安全的得到 this 指针的 shared_ptr 版本。
获取 this 的 shared_ptr 版本
①.概述
shared_ptr 是通过引用计数来判断对象是否可以被销毁。
②.通过 this 创建 shared_ptr
多次通过原始指针创建 shared_ptr 不会增加引用计数,且会造成内存重复释放
直接使用shared_ptr
class demoClass
{
public:
demoClass() { cout << "构造函数" << endl; }
~demoClass() { cout << "析构函数" << endl; }
void Func()
{
shared_ptr<demoClass> dC(this);
cout << "引用计数次数:" << dC.use_count() << endl;
}
};
int main()
{
demoClass* demo = new demoClass;
shared_ptr<demoClass> sp(demo);
cout << "引用计数次数:" << sp.use_count() << endl;
demo->Func();
return 0;
}
运行结果:会报错
原因:
main函数中,shared_ptr<demoClass> sp(demo)用原始指针demo初始化,此时sp的引用计数为1(管理demo指向的对象)。- 调用
demo->func()时,func函数内部用shared_ptr<demoClass> sp(this)创建了一个新的shared_ptr,它也指向this(即demo指向的同一个对象)。
但这两个shared_ptr(main中的sp和func中的sp)是完全独立的(使用同一个地址创建了两个shared_ptr,调用的的都是构造函数,因为使用的并不是对象,没有调用拷贝构造,所以没有维护共同的引用计数)—— 它们没有共享同一个引用计数(各自维护自己的计数,初始都是1)。
func函数执行结束时,内部的sp被销毁,其引用计数减为0,于是会调用demoClass的析构函数,释放demo指向的内存。main函数执行结束时,main中的sp被销毁,其引用计数也减为0,会再次尝试释放已经被释放的内存(此时demo指向的内存已无效)。
这种 “双重释放” 是 C++ 中严重的未定义行为,会直接导致程序崩溃。
使用enable_shared_from_this
class demoClass : public enable_shared_from_this<demoClass>
{
public:
demoClass() { cout << "构造函数" << endl; }
~demoClass() { cout << "析构函数" << endl; }
void Func()
{
auto dC = shared_from_this();
cout << "引用计数次数:" << dC.use_count() << endl;
}
};
int main()
{
demoClass* demo = new demoClass;
shared_ptr<demoClass> sp(demo);
cout << "引用计数次数:" << sp.use_count() << endl;
demo->Func();
return 0;
}

注意:
enable_shared_from_this<T>的shared_from_this()函数必须在对象已被shared_ptr管理的前提下才能调用,不然会导致调用shared_from_this()时触发未定义行为(通常会抛出std::bad_weak_ptr异常)- 如需在类内部获取自身的
shared_ptr,必须通过enable_shared_from_this的shared_from_this()方法,确保计数共享。
更多推荐
所有评论(0)