简体   繁体   English

接口中的纯虚拟析构函数

[英]Pure virtual destructor in interface

Here is my problem: I'm making a C++ DLL which relies extensively on instance object exports. 这是我的问题:我正在制作一个C ++ DLL,它广泛依赖于实例对象导出。 So I return my actual instances as a pointers to an interface through some exported factory method. 因此,我通过一些导出的工厂方法将实际实例作为指向接口的指针返回。

The interfaces I use are purely virtual, to avoid linking problems. 我使用的接口是纯虚拟的,以避免链接问题。 So I need a pure virtual destructor too, and I implemented one (with empty body, as I googled it). 所以我也需要一个纯粹的虚拟析构函数,并且实现了一个(用空的主体,就像我用谷歌搜索的那样)。 All compiles perfectly well, except... I can't see if the actual destructors are called or not - because when I added some 所有的编译都很好,除了...我看不到实际的析构函数是否被调用-因为当我添加一些

std::cout << "hello destructor";
I never get to see it. 我从来没有看到它。

I have some explicit "delete obj" (EDIT: and it is called from the "FreeObject" method inside the DLL), that's not the problem. 我有一些显式的“删除obj”(编辑:它是从DLL中的“ FreeObject”方法调用的),这不是问题。

Am I missing something? 我想念什么吗? Is there another way to delete my object through an interface? 还有另一种通过接口删除对象的方法吗?

EDIT: Again, I don't have memory management inconsistency, it's all inside the DLL. 编辑:再次,我没有内存管理不一致,它都在DLL中。 But the right destructor just isn't called. 但是只是没有调用正确的析构函数。

You shouldn't mix and match calls to new and delete across DLL boundaries. 您不应该跨DLL边界混合和匹配对newdelete调用。

Instead, I'd recommend the tried-and-true method that COM uses: AddRef and Release . 相反,我建议COM使用的经过验证的方法: AddRefRelease When the reference count hits zero, Release calls delete this; 当引用计数达到零时, Release调用delete this; from inside the DLL, ensuring that new and delete are matched. 从DLL内部,确保newdelete匹配。

This is how I solved your particular problem for dynamically loaded C++ classes - 这就是我为动态加载的C ++类解决您的特定问题的方式-

Have a base class for all pluggable objects, ie 具有所有可插拔对象的基类,即

class object_t {

 public:
  virtual ~object_t();

 //other type utils...

};

Have an base interface for all plugin interfaces, ie 具有所有插件接口的基本接口,即

class object_t;

class interface_t {

 public:
  virtual object_t* object() = 0;

}

object_t will have linkage, define it in its own dll that you will link against plugin classes. object_t将具有链接,在您自己的dll中定义该链接,您将针对插件类进行链接。 Other useful hooks to have in object_t are copying, spawning, RTTI and other type utils, my base object has spawn(), copy(), object_name() for example. 在object_t中具有其他有用的钩子是复制,生成,RTTI和其他类型的utils,例如,我的基础对象具有spawn(),copy(),object_name()。

So all concrete classes derive from object_t and their respective pure virtual interface type, and all published (pluggable) interfaces derive from interface_t. 因此,所有具体类均源自object_t及其各自的纯虚拟接口类型,所有已发布(可插入)接口均源自interface_t。

Then you can load a plugin, instantiate the interface using your factory and delete thusly - 然后,您可以加载插件,使用工厂实例化接口,然后删除-

delete interface->object()

And as object_t has a virtual destructor the correct destructor will be called. 并且由于object_t具有虚拟析构函数,因此将调用正确的析构函数。

Theres no problem with where you delete the object under linux, its fine under window's if all plugins/executables are linked against the same dynamic (dll) CRT. 在Linux下删除对象没有问题,如果所有插件/可执行文件都链接到同一个动态(dll)CRT,则在窗口下删除对象就很好。

You don't need destructor in the interface at all. 您根本不需要在接口中使用析构函数。 Proper destructor must be seen only by delete caller. 正确的析构函数只能由delete调用者看到。 Outside the DLL, use an interface pointer as a handle, not something you can create / destroy. 在DLL之外,请使用接口指针作为句柄,而不是可以创建/销毁的东西。 Object construction / destruction should be be inside the DLL. 对象的构造/破坏应该在DLL内部。 You can use reference counting or any other technique you want, just provide proper exports to access and manipulate objects, you decide how much memory management will be encapsulated. 您可以使用引用计数或任何其他所需的技术,只需提供适当的导出来访问和操作对象,即可决定要封装多少内存管理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM