就像标题所说的那样。以下设计的示例似乎适用于键盘:http://codepad.org/4cgGmvDQ和我的Linux机箱上的GCC 4.1.2。
#include<stdlib.h>
#include<new>
class IBase
{
public:
virtual ~IBase(){}
};
class B : public IBase
{
public:
virtual ~B(){}
};
class D : public B
{
public:
virtual ~D(){ }
};
int main()
{
void* p = malloc(sizeof(D));
D* d = new(p) D();
B* b = static_cast<B*>(d);
b->~IBase();
free(p);
}
但Visual Studio Pro 2012 11.0.61030.00 Update 4失败并显示:
main.cpp(30): error C2300: 'B' : class does not have a destructor called '~IBase'
显然,这个例子可以很容易地重做以避免这个问题,但我的实际代码库并没有给我任何其他选择。是否有人熟悉Microsoft编译器的这种特殊失败?
答案 0 :(得分:3)
这不是MSVC中的错误。从标准,§3.4.5[basic.lookup.classref] / p2-3(引用N3936,强调我的):
如果类成员访问(5.2.5)中的 id-expression 是 unqualified-id ,[...]
如果 unqualified-id 为
~type-name
,则会查找 type-name 在整个 postfix-expression 的上下文中。如果是T
的类型 对象表达式是类类型C
,类型名称也是 在班级C
的范围内查找。 至少有一个查找 应找到一个名称(可能是cv-qualified)T
。
在您的代码中,T
为B
,查找IBase
显然无法找到引用B
的名称。因此,您的代码格式不正确。如果g ++接受它,它可能是错误或扩展。
由于听起来实际的B
代表的类型在您的实际代码中是“不可言说的”,但IBase
可以写,最简单的解决方案就是将b
转换为IBase *
。
答案 1 :(得分:-1)
这是一个已知的错误。至于“为什么”失败,我没有答案。您的示例的解决方法可能是:
B-&GT; I基准::〜广积();
答案 2 :(得分:-1)
自动调用基类析构函数。如果手动调用基类析构函数,那么当对象被销毁时,它将再次调用。