此代码是否会导致定义的行为?
class A {
int x;
};
class B {
short y;
};
class C {
double z;
};
class D : public A, public B, public C {
float bouncy;
};
void deleteB(B *b) {
delete b;
}
void is_it_defined() {
D *d = new D;
deleteB(d);
B *b = new D; // Is this any different?
delete b;
}
如果没有定义,为什么不呢?如果是,它定义的是什么以及为什么?最后,如果它的实现定义了,你能举例说明一个常见的实现可能会定义行为吗?
答案 0 :(得分:6)
引用Herb Sutter:
如果可以执行删除 多态地通过基类 接口,然后它必须表现 虚拟而且必须是虚拟的。确实, 语言需要它 - 如果你 多态删除没有 虚拟析构函数,你召唤 可怕的幽灵“未定义 行为”。
在您的示例中,delete
都是通过基类指针执行的,并产生未定义的行为。标准5.3.5(删除):
在第一种选择中(删除 object),如果是静态类型的 操作数与其动态不同 类型,静态类型应为基础 操作数的动态类型的类 而静态类型应该有一个 虚拟析构函数或行为是 未定义强>
此处,delete
对静态类型B
起作用,而操作数的动态类型为D
。
答案 1 :(得分:0)
B
没有虚拟析构函数,它应该有。
答案 2 :(得分:-1)
是否关注虚拟析构函数? 看看这个:
class A
{
int x;
public:
virtual void fun()
{
return;
}
};
class D : public A
{
float bouncy;
};
void is_it_defined()
{
A *b = new D; // it`s ok!
delete b;
}
你知道吗?没关系。指针b可以正确删除。
所以,只需要一个虚拟函数来激活多态。