我正在尝试更改我当前的设计并想要使用智能指针(最好是unique_ptr
作为 Herb Sutter 说,如有疑问,请默认使用unique_ptr
)但是我很困惑当前的设计中哪个适合一个指针将传递给多个类。
示例代码如下
class X {
private:
ZHandler* _mZHandler; //change it as unique_ptr or shared_ptr??
public:
X()
{
Z* zPtr = createUsingFactory(); // instantiated by legacy code factory function, createUsingFactory() is just representational
_mZHandler = new ZHandler(zPtr);
}
~X()
{
delete _mZHandler;
}
void callYfunc()
{
_mZHandler->funcY();
}
};
//ZHandler wraps the calls to Z as well as serves as event listner to Z
class ZHandler : public Z::ZEventListner {
private:
Z* _mPtrZ;
public:
ZHandler(Z* ptr) : _mPtrZ(ptr){}
void funcY()
{
_mPtrZ->funcZ();
}
void funcNotifyEvent
{
}
};
class Z {
private:
ZEventListner* _mZEventListner;
public:
class ZEventListner{
vitual void funcNotifyEvent() = 0;
};
void setEventListner(ZEventListner* ptr)
{
_mZEventListner = ptr;
}
ZEventListner* getEventListner(){return _mZEventListner};
void funcZ(){}
void funcNotify() //called by some other class
{
_mZEventListner->funcNotifyEvent();
}
};
问题是在class X
中使用unique_ptr
还是shared_ptr
进行ZHandler
指针?(因此,功能和指针将在其他类别中发生变化),如果我使用unique_ptr
,那么我必须在setEventListner
函数中移动ZHandler
的PTR,一旦我这样做,原始指针将丢失,并且将不可能从X
拨打ZHandler
。
智能指针都大于所有权。这意味着哪些对象负责删除其成员。因此,您应该查看哪些对象 delete 他们有指针的东西。
如果设计是不可能知道哪个指针将是最后一个引用对象的指针(因此是用于删除它的对象),则应使用std::shared_ptr
。
另一方面,只有一个一个指针会超过所有其他引用,并且始终需要是删除对象的一个,那应该是std::unique_ptr
。
大多数拥有指针(需要删除内容的指针)倾向于std::unique_ptr
。
如果您有一个指向将始终的对象指针,请越过指针并被某些其他对象删除,则应使用 RAW POINTER 或最好是 a 参考。
因此,您必须确定设计中的哪些对象将 live 最长,哪些对象将负责销毁它们指向并相应地选择您的指针的对象。
共享指针:当您不知道哪个指针必须删除对象时,因为您不知道哪个指针会超出范围(或被删除)。
唯一的指针:当指向对象将从一个地方和所有其他裁判中销毁该对象的所有其他裁判时,该对象的所有其他裁判都将在此指针需要删除之前已过期。
原始指针/参考:当其他人负责删除对象时,因为此指针/参考的访问对象的需求将在发生之前已过期。
这不是对问题的直接答案,而是一种避免与智能指针混淆的方法。首先,请勿使用unique_ptr或shared_ptr。取而代之的是花一天的时间来了解RAII并尝试实现自己的" unique_ptr"(您可以查看STL代码)。这将使您了解unique_ptr的工作原理。然后尝试实现自己的" shared_ptr"。实施您自己的共享PTR的最简单方法是使用内部参考计数的对象。
在您了解了它们的工作方式后,使用unique_ptr或shared_ptr松动它的魔术,您应该知道。