我有一个关于虚拟析构函数的问题。我知道如果变量指针是多态的,那么创建一个虚拟析构函数是必要的,但是如果我不需要做任何破坏,那么特定代码是否必要?
例如,以下代码:
struct Foo
{
struct ExtraData
{
int myType;
}
struct BarData : public ExtraData
{
std::string myName;
float myFoo;
}
struct BooData : public ExtraData
{
int myBoo;
double myTime;
}
Foo() {}
~Foo() { delete myExtradata; }
int myA;
int myB;
ExtraData* myExtraData;
};
myExtraData是从struct外部创建的,它可以通过new BarData()或通过新的BooData()。 BarData和BooData是否需要虚拟析构函数。或者因为他们没有成员指针,这没关系?
答案 0 :(得分:6)
打电话给UB:
Base* base = new Derived;
delete base; // UB here if ~Base is not virtual.
除非Base
的析构函数为virtual
。
5.3.5 / 3删除
在第一个备选(删除对象)中,如果操作数的静态类型与其动态类型不同,则静态类型应为操作数的动态类型的基类,静态类型应具有虚拟析构函数或者行为未定义。在第二种方法(删除数组)中,如果要删除的对象的动态类型与其静态类型不同,则行为是未定义的.73)
在您的情况下,“操作数的静态类型”为ExtraData
,“其动态类型”为BarData
或BooData
。所以它们是不同的,静态类型ExtraData
必须有一个虚拟析构函数。
答案 1 :(得分:2)
执行delete myExtradata;
时,删除必须知道如何为删除的对象调用正确的析构函数。为了使其以多态方式工作,ExtraData
需要有一个虚拟析构函数。
这不仅需要指针,但在这种特定情况下,我确信std::string
中的BarData
内部至少有一个指针。