接口中的纯虚拟析构函数

时间:2010-06-15 02:55:36

标签: c++ destructor

这是我的问题:我正在制作一个C ++ DLL,它广泛依赖于实例对象导出。 所以我通过一些导出的工厂方法返回我的实际实例作为接口的指针。

我使用的接口纯粹是虚拟的,以避免链接问题。所以我也需要一个纯粹的虚拟析构函数,并且我实现了一个(使用空体,因为我用Google搜索它)。 所有编译完全正常,除了...我无法看到是否调用了实际的析构函数 - 因为当我添加一些

std::cout << "hello destructor";
时,我永远不会看到它。

我有一些明确的“删除obj”(编辑:它是从DLL里面的“FreeObject”方法调用的),这不是问题。

我错过了什么吗?有没有其他方法可以通过界面删除我的对象?

编辑:同样,我没有内存管理不一致,它都在DLL内部。但是没有调用正确的析构函数。

3 个答案:

答案 0 :(得分:4)

您不应该跨越DLL边界混合和匹配newdelete的调用。

相反,我建议使用COM使用的经过验证的方法:AddRefRelease。当引用计数达到零时,Release会从DLL内部调用delete this;,确保匹配newdelete

答案 1 :(得分:1)

这就是我为动态加载的C ++类解决特定问题的方法 -

拥有所有可插入对象的基类,即

class object_t {

 public:
  virtual ~object_t();

 //other type utils...

};

为所有插件接口提供基本接口,即

class object_t;

class interface_t {

 public:
  virtual object_t* object() = 0;

}

object_t将具有链接,在其自己的dll中定义它,您将链接插件类。在object_t中有其他有用的钩子是复制,产生,RTTI和其他类型的工具,我的基础对象有例如spawn(),copy(),object_name()。

因此,所有具体类都派生自object_t及其各自的纯虚拟接口类型,所有已发布(可插入)的接口都派生自interface_t。

然后你可以加载一个插件,使用你的工厂实例化界面并删除 -

delete interface->object()

由于object_t有一个虚析构函数,因此将调用正确的析构函数。

如果所有插件/可执行文件都链接到相同的动态(dll)CRT,那么在linux下删除对象的位置没有问题,如果所有插件/可执行文件都链接在一起,那么它在窗口下是很好的。

答案 2 :(得分:0)

根本不需要界面中的析构函数。只有delete调用者才能看到正确的析构函数。在DLL之外,使用接口指针作为句柄,而不是你可以创建/销毁的东西。对象构造/销毁应该在DLL内部。您可以使用引用计数或任何其他技术,只需提供适当的导出来访问和操作对象,您可以决定将封装多少内存管理。