如何在多个 类 中使用相同的 unique_ptr

How to use same unique_ptr in multiple classes

我正在尝试更改我当前的设计并希望使用智能指针(最好是 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中的ZHandler指针是用unique_ptr还是shared_ptr? (因此函数和指针将在其他 类 中发生变化), 如果我使用 unique_ptr 那么我必须在 setEventListner 函数中移动 ZHandler 的 ptr,一旦我这样做,原始指针将丢失并进一步调用 ZHandlerX 不可能。

这不是对问题的直接回答,而是一种避免与智能指针混淆的方法。首先,不要使用 unique_ptr 或 shared_ptr。相反,花一天时间了解 RAII 并尝试实现您自己的 "unique_ptr"(您可以查看 stl 代码)。这将使您了解 unique_ptr 的工作原理。然后尝试实现你自己的"shared_ptr"。实现您自己的共享指针的最简单方法是围绕使用内部引用计数的对象。

了解它们的工作原理后,使用 unique_ptr 或 shared_ptr 会失去它的魔力,您应该知道何时使用哪个。

智能指针都是关于所有权。这意味着哪些对象负责删除它们的成员。所以你应该看看哪些对象删除了它们指向的东西。

如果设计无法知道哪个指针将是最后一个引用对象(因此是用于删除它的指针),那么您应该使用 std::shared_ptr

另一方面,如果只有 一个 指针将比所有其他引用更持久,并且始终需要是对象被删除的指针,那么应该是 std::unique_ptr.

大多数拥有指针(需要删除东西的指针)往往是std::unique_ptr

如果您有一个指向某个对象的指针,该对象总是比该指针长寿并被其他对象删除,那么您应该使用原始指针最好一个引用.

所以你必须决定在你的设计中哪些对象存活最长,哪些对象将负责销毁它们指向的对象并相应地选择你的指针。

共享指针:当您不知道哪个指针将不得不删除对象时,因为您不知道哪个指针最后会超出范围(或被删除)。

唯一指针:当指向的对象将从恰好一个地方被销毁,并且该对象的所有其他裁判在该指针需要删除它之前已经过期。

Raw pointer/Reference:当其他人负责删除该对象时,因为此pointer/reference访问该对象的需要在此之前已经过期发生了。