std :: unique_ptr的自定义删除程序是否是手动调用析构函数的有效位置? [英] Is custom deleter for std::unique_ptr a valid place for manual call to destructor?

查看:507
本文介绍了std :: unique_ptr的自定义删除程序是否是手动调用析构函数的有效位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a very basic implementation of reflection that includes a Type class which does object instantiation for the class it describes. Stripped down to the relevant parts, it looks like this:

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)();
    };

}

Type.cpp:

Type::Type(PluginPtr(*createInstance_Handler)()) :
    _createInstance_Handler(createInstance_Handler) {}

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

实际的实例化逻辑包含在Plugin类中(以及每个后代中):

The actual instantiation logic is housed in the Plugin class (and also in each of its descendants):

Plugin.h:

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

Plugin.cpp

Plugin.cpp

Plugin::~Plugin() {}

const Reflection::Type Plugin::Type(CreateInstance);

PluginPtr Plugin::CreateInstance() { return PluginPtr(new Plugin); }

当我尝试对此进行编译时,出现以下错误(在Visual Studio 2013中):

When I attempt to compile this, I get these errors (in 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的删除器引起的(在正在操作的类的类定义中发现自己).我在某处读到,如果我提供自己的删除器,此问题将消失.所以我重新定义了PluginPtr:

I dug around a bit, and apparently this is caused by the deleter of the std::unique_ptr (finding itself inside the class definition of the class it is operating on). I read somewhere that if I supply my own deleter, this problem goes away. So I redefined PluginPtr to this:

typedef std::unique_ptr<Plugin, PluginDeleter> PluginPtr

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

The (compilation) problem does indeed go away, but the question then, is can/should this PluginDeleter call ~Plugin() manually (to ensure that the plugin (and any derived object that the PluginPtr might be pointing to!) is properly destructed)? And where/how should I best declare/define it, so that I don't get the same problem with incomplete types?

(或者是否有更好的方法?)

(or is there a better way altogether?)

PS.现在,在处理我的源代码时,我意识到上面的代码有错误. Type.cpp的最后一行应显示为

PS. Working on my source code now, I realize that there's an error in the above code. The last line in Type.cpp should read

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

推荐答案

std::unique_ptr的删除程序应删除该对象,即销毁它(如您可以假定的那样),然后在以下情况下释放所使用的内存需要.

The deleter of std::unique_ptr should delete the object, that is to say destroy it (as you can assume it should be), then free the memory used if needed.

如果您的自定义删除程序使用delete运算符,则不必以以下方式手动调用析构函数:

If your custom deleter uses the delete operator, then you don't have to manually call the destructor as:

delete是具有非常特定行为的运算符:表达式 使用delete运算符,首先调用适当的析构函数(对于 类类型),然后调用函数运算符delete(即 功能)以释放存储空间.

delete is an operator with a very specific behavior: An expression with the delete operator, first calls the appropriate destructor (for class types), and then calls function operator delete (i.e., this function) to release the storage.

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

If you create the pointer using statically allocated memory or a placement-new in a statically allocated memory or a memory you won't free until the application exit (for example), then you should not call the delete operator but you still have to destroy the object, thus you have to call the destructor of the object.

这篇关于std :: unique_ptr的自定义删除程序是否是手动调用析构函数的有效位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆