C++ 使用std::unique_ptr.reset()更改指针下的对象

C++ 使用std::unique_ptr.reset()更改指针下的对象,c++,c++11,smart-pointers,C++,C++11,Smart Pointers,我想使用代理设计模式,以便能够“使”我的对象的功能失效。在我的设计中,用作无效对象的NullObject是一个静态变量 使用std::unique_ptr.reset和指向静态变量的指针是解决此问题的合法方法吗 我曾尝试在VisualStudio中执行此操作,所有操作都正常工作,但我担心唯一的_ptr析构函数以及它可能希望如何处理静态变量 class Proxy : public IExtendedInterface { public: Proxy(std::unique_ptr<

我想使用代理设计模式,以便能够“使”我的对象的功能失效。在我的设计中,用作无效对象的NullObject是一个静态变量

使用std::unique_ptr.reset和指向静态变量的指针是解决此问题的合法方法吗

我曾尝试在VisualStudio中执行此操作,所有操作都正常工作,但我担心唯一的_ptr析构函数以及它可能希望如何处理静态变量

class Proxy : public IExtendedInterface
{
public:
    Proxy(std::unique_ptr<IInterface> object)
       : heldObject(std::move(object))
    {}
    void invalidate() override
    {
        heldObject.reset(&nullObject);
    }
    void someMethod() override
    {
        heldObject->someMethod();
    }
private:
    std::unique_ptr<IInterface> heldObject;
    static NullObject nullObject;

};

class Object : public IInterface
{
public:
    void someMethod() override
    {
        std::cout << "Called from object";
    };

class NullObject : public IInterface
{
public:
    void someMethod() override
    {
        std::cout << "Called from NullObject";
    };
};
类代理:公共IExtendedInterface
{
公众:
代理(std::unique_ptr对象)
:heldObject(标准::移动(对象))
{}
void invalidate()重写
{
heldObject.reset(&nullObject);
}
void someMethod()重写
{
HeldoObject->someMethod();
}
私人:
std::唯一的直升机项目;
静态空对象空对象;
};
类对象:公共接口
{
公众:
void someMethod()重写
{

std::cout您不需要任何特殊的null对象,您只需调用
std::unique_ptr.reset()
std::unique_ptr::operator bool
将返回false,指示指针持有null指针,不应取消引用


另外请注意,使
唯一\u ptr
指向静态分配的对象,如果该对象在此状态下超出范围,可能会导致双重自由问题。

这是一个有趣的问题。首先,我想质疑是否需要“null”对象。它们确实有其用途,但还有其他方法

一个解决方案是简单地为每个指针创建一个新的“独特的”代码> nuldLoops<代码>,但是如果您确定只有<强> > < >代码> nulLobjult<代码>,那么可以考虑单模式。

静态对象的一个问题是您无法始终控制它们的创建时间和销毁时间。单例模式解决了创建问题,但销毁问题取决于您的情况

如果永远不需要调用
NullObject
的析构函数,您可以简单地使用基于指针的singleton,它永远不会被销毁

然后,您可以为您的
unique\u ptr
创建一个自定义删除器,以避免删除单例

大概是这样的:

class Object
{
public:
    virtual ~Object() = default;
};

// make this inline or extern (and define it elsewhere)
// to ensure only one instance
inline Object* null_object()
{
    // create the null version here
    class NullObject: public Object{};

    // Never gets deleted so it is SAFE during program close-down
    // ASSUMING calling its destructor is not required!
    static NullObject* null_object = new NullObject;

    return null_object;
}

// special deleter avoids deleting the null object
struct ObjectDeleter
{
    void operator()(Object* o) const
    {
        if(o != null_object())
            delete o;
    }
};

// special version of a unique_ptr that uses the deleter
using ObjectUniquePtr = std::unique_ptr<Object, ObjectDeleter>;

在静态分配的对象上创建一个唯一的_ptr点不是一个好主意(事实上,您将进入UB land)。当您想处理动态分配的对象时,您可以使用智能指针。我知道,但我需要通过构造函数移动的动态分配对象的唯一\u ptr。唯一\u ptr没有问题,问题是您使用静态分配的对象来指示指针不再使用。因此我应该让heldObject和静态nullObject都成为共享对象吗?我根本不相信你需要一个nullObject。对于通过指针引用的静态分配对象,即使是一个free也是错误的。
auto op = ObjectUniquePtr(null_object());