std::unique_ptr的自定义deleter是手动调用析构函数的有效位置吗



我有一个非常基本的反射实现,其中包括一个Type类,它为它所描述的类进行对象实例化。剥离到相关部分,它看起来像这样:

类型.h:

class Plugin; // forward declaration
typedef std::unique_ptr<Plugin> PluginPtr;
namespace Reflection {
class Type {
public:
explicit Type(PluginPtr(*)());
PluginPtr CreateInstance();
private:
PluginPtr(*_createInstance_Handler)();
};
}

类型.cpp:

Type::Type(PluginPtr(*createInstance_Handler)()) :
_createInstance_Handler(createInstance_Handler) {}
PluginPtr CreateInstance() { return (*_createInstance_Handler)(); }

实际的实例化逻辑包含在Plugin类中(也包含在它的每个子类中):

插件.h:

class Plugin {
public:
virtual ~Plugin();
static const Reflection::Type Type;
private:
static PluginPtr CreateInstance();

插件.cpp

Plugin::~Plugin() {}
const Reflection::Type Plugin::Type(CreateInstance);
PluginPtr Plugin::CreateInstance() { return PluginPtr(new Plugin); }

当我试图编译它时,我会收到以下错误(在Visual Studio 2013中):

error C2027: use of undefined type 'Plugin'
error C2338: can't delete an incomplete type
warning C4150: deletion of pointer to incomplete type 'Plugin'; no destructor called

我仔细研究了一下,很明显,这是由std::unique_ptr的deleter(发现自己在其操作的类的类定义中)引起的。我在某个地方读到,如果我提供自己的deleter,这个问题就会消失。所以我将PluginPtr重新定义为:

typedef std::unique_ptr<Plugin, PluginDeleter> PluginPtr

(编译)问题确实消失了,但问题是,这个PluginDeleter是否可以/应该手动调用~Plugin()(以确保插件(以及PluginPtr可能指向的任何派生对象!)被正确地销毁)?我应该在哪里/如何最好地声明/定义它,这样我就不会遇到不完整类型的同样问题?

(或者有更好的方法吗?)

PS。现在我正在编写源代码,我意识到上面的代码中有一个错误。Type.cpp中的最后一行应为

PluginPtr CreateInstance() { return (_createInstance_Handler)(); }

std::unique_ptr的deleter应该删除对象,也就是说销毁它(你可以假设它应该是),然后在需要时释放所用的内存。

如果您的自定义deleter使用delete运算符,那么您不必手动将析构函数调用为:

delete是一个具有特定行为的运算符:表达式使用delete运算符,首先调用相应的析构函数(用于类类型),然后调用函数运算符delete(即功能)来释放存储器。

如果使用静态分配的内存或静态分配内存中的新位置创建指针,或在应用程序退出之前无法释放的内存(例如),则不应调用delete运算符,但仍必须销毁对象,因此必须调用对象的析构函数。

相关内容

最新更新