enable_shared_from_this的主要作用是用来安全地获取指向这个类(即继承enable_shared_from_this模板的类)的指针,有人会说,c++类不是都有默认的this用来指向这个类吗,何必还要再采用enable_shared_from_this的方法呢,大家先从一个例子来看用this指针会存在的问题:
#include<memory>
#include<iostream>
class CSharePtr{
public:
CSharePtr();
~CSharePtr();
std::shared_ptr<CSharePtr> get_Ptr()
{
std::shared_ptr<CSharePtr> ptr(this);
return ptr;
}
};
typedef std::shared_ptr<CSharePtr> sharePtr;
//.cpp
#include "SharePtr.h"
CSharePtr::CSharePtr()
{
std::cout << "create" << std::endl;
}
CSharePtr::~CSharePtr()
{
std::cout << "destroy" << std::endl;
}
//main
void main()
{
CSharePtr* pShPtr = new CSharePtr;
sharePtr pr(pShPtr);
sharePtr pr1 = pr->get_Ptr();
int iUseCount = pr.use_count();
}
运行结果:构造函数调用了一次,而析构函数调用了两次,而IUseCount为1
问题就严重了,尤其是大型项目中,这种问题比较难排查的,为什么会是这种结果呢,因为给std::shared_ptr<CSharePtr>传递的this不能增加引用计数。那么怎么避免这种情况呢,将这个类继承std::enable_shared_from_this<CSharePtr>,并用shared_from_this()来获取指向类本身的指针,如下所示
#include<memory>
#include<iostream>
class CSharePtr:public std::enable_shared_from_this<CSharePtr>
{
public:
CSharePtr();
~CSharePtr();
std::shared_ptr<CSharePtr> get_Ptr()
{
return shared_from_this();
}
};
typedef std::shared_ptr<CSharePtr> sharePtr;
//,cpp
#include "SharePtr.h"
CSharePtr::CSharePtr()
{
std::cout << "create" << std::endl;
}
CSharePtr::~CSharePtr()
{
std::cout << "destroy" << std::endl;
}
void main()
{
CSharePtr* pShPtr = new CSharePtr;
sharePtr pr(pShPtr);
sharePtr pr1 = pr->get_Ptr();
int iUseCount = pr.use_count();
}
运行结果:一次构造,一次析构,iUseCount为1,正常