有些類的成員函數需要獲得自身的std::shared_ptr掠抬,但不能就地從this創(chuàng)建,這樣會導致多個毫無關系的智能指針引用到同一個對象绍载,導致重復釋放【不能傳遞share_ptr<this>诡宗,因為這樣會造成2個以上非共享的share_ptr指向同一個對象,未增加引用計數導對象被析構兩次】击儡。
std::enable_shared_from_this<>模版類就是解決這個問題塔沃。
請看regTo的實現,就需要使用本身的智能指針阳谍。
class base : public std::enable_shared_from_this<base>
{
std::string msg;
public:
base(std::string s) : msg(s){}
virtual ~base() = default;
virtual void print()
{
std::cout << msg << std::endl;
}
void regTo(class regObj*);
};
class regObj
{
std::vector<std::shared_ptr<base>> objs;
public:
void regobject(std::shared_ptr<base> shp)
{
objs.push_back(shp);
}
void print()
{
for (auto& c : objs)
c->print();
}
};
void base::regTo(class regObj* p)
{
p->regobject(this->shared_from_this());
}
class concrete1 : public base
{
public:
concrete1(const char* msg) : base(msg){}
};
class concrete2 : public base
{
public:
concrete2(const char* msg) : base(msg) {}
};
int main(int,const char**)
{
auto instance = new regObj;
auto p1 = std::make_shared<concrete1>("concreteObj1");
std::shared_ptr<concreate2> p2(new concrete2("concreteObj2"));
p1->regTo(instance);
p2->regTo(instance);
instance->print();
delete instance;
}
上面regTo函數就需要獲得本身的shared_ptr蛀柴。
注意:調用這個函數的實例必須是構建在shared_ptr上的。因為shared_from_this是從一個weak_ptr構建的一個shared_ptr,這里的weak_ptr是一個shared_ptr弱引用矫夯。如果本身沒有構建名扛,自然弱引用也是空的。
如果如下所示的使用茧痒,則會發(fā)生運行時錯誤:
auto ptr = new concrete2("concreteObj3");
ptr->regTo(instance);
拋出異常的位置在這里:
template<class _Ty2,
enable_if_t<_SP_pointer_compatible<_Ty2, _Ty>::value, int> = 0>
explicit shared_ptr(const weak_ptr<_Ty2>& _Other)
{ // construct shared_ptr object that owns resource *_Other
if (!this->_Construct_from_weak(_Other))
{
_THROW(bad_weak_ptr{});
}
}