【发布时间】:2015-05-26 14:39:01
【问题描述】:
我有一个基本接口(在 Visual Studio 2013 中对接口使用 Microsoft 的 C++ 语法),它公开了如下简单功能:
__interface IDisposable {
void Dispose();
};
__interface IBase : public IDisposable {
void Foo();
void Bar();
};
有一种特定类型的类必须继承这些方法,因此这些类具有以下结构:
class Derived : public IBase {
public:
Derived();
~Derived();
void Dispose();
void Foo();
void Bar();
}
这些类也有一些变量,我想使用智能指针,但这些指针确实产生了泄漏,因为在以下场景中没有调用析构函数 ~Derived():
- 我有一个
Stack<IBase*>来处理一堆这些对象(例如Derived、Derived2等)。 - 一旦最顶层的元素 (
pCurrent) 应该从堆栈中删除相应的数据 (m_Data) 我正在调用方法来处理资源:((IDisposable*)pCurrent->m_Data)->Dispose(); - 这个调用后面跟着一个
delete pCurrent->m_Data,它显然试图调用~IBase(),它显然不存在,因为它是一个接口。因此提到的~Derived()也不会被调用,Derived中的任何智能指针也不会被删除,这会导致严重的内存泄漏。
令人惊讶的是手动删除工作:
auto p = new Derived();
delete p; // ~Derived() is properly called as we are not handling a IBase* object
我在考虑使用虚拟析构函数,但无法在这些接口中定义析构函数以使 ~Derived() 也成为虚拟。
是否有更好的方法来调用正确的析构函数?
【问题讨论】:
-
你试过虚拟析构函数吗?
-
@ddriver 即使使用
virtual ~Derived(),在所描述的场景中也不会调用此函数。 -
您应该从多态层次结构的最底部以及接口进行虚拟破坏。
-
@ddriver 这也让我想到了,但documentation 提到接口不能包含构造函数、析构函数或运算符。这是否意味着我必须重新考虑层次结构并用纯虚函数制作抽象基类,而不是使用
__interface关键字来简化代码? -
当然可以,C++ 中没有接口之类的东西,你应该放弃那个关键字,那就是 MS BS。它只是类,因此它们可以同时具有构造函数和析构函数,即使它们的某些方法是抽象的,因此实际的“接口”类也是抽象的。
标签: c++ c++11 interface virtual destructor