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