我想我在MSVC的编译器中发现了一个错误(MSVC Ultimate 2012 Version 11.0.61030.00 Update 4)。
#include "stdafx.h"
class Base
{
public:
Base()
{
}
void print()
{
printf("Base::print()\n");
}
};
class Derived : public Base
{
public:
Derived() : Base()
{
}
virtual void print()
{
printf("Derived::print()\n");
}
};
class DerivedSquared : public Derived
{
public:
DerivedSquared() : Derived()
{
}
void print()
{
printf("DerivedSquared::print()\n");
}
};
int main(int argc, char *argv[])
{
Base *obj1 = new Base();
Base *obj2 = new Derived();
Base *obj3 = new DerivedSquared();
obj1->print();
obj2->print();
obj3->print();
// Memory leaks are ALWAYS nasty :P
delete obj1;
// CRASH!!!
// File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp
// _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
delete obj2;
delete obj3;
return 0;
}
该代码的特殊性在于Base的printf()方法不是虚拟的,而Derived的是。 GCC不会发生这种情况(我已用codepad测试过)。 我想知道这是否是一个真正的编译器错误,或者我错过了一些明显的东西。
思想?
答案 0 :(得分:4)
5.3.5 / 3 在第一个备选方案(删除对象)中,如果要删除的对象的静态类型与其不同 动态类型,静态类型应该是要删除的对象的动态类型的基类 静态类型应具有虚拟析构函数或行为未定义。
强调我的。崩溃是未定义行为的一种可能表现。 "似乎没有发生任何不良事件"是另一个。
答案 1 :(得分:2)
问题出现时没有调用'print'函数,可以通过向每个类添加一个虚析构函数来解决。
答案 2 :(得分:0)
至于我,那看起来像个bug。我的意思是如果您正在谈论这个问题,则调用以崩溃结束的打印功能。