非指针成员变量的虚拟析构函数

时间:2017-10-06 11:57:34

标签: c++ c++11 pointers destructor

我有一个关于虚拟析构函数的问题。我知道如果变量指针是多态的,那么创建一个虚拟析构函数是必要的,但是如果我不需要做任何破坏,那么特定代码是否必要?

例如,以下代码:

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是否需要虚拟析构函数。或者因为他们没有成员指针,这没关系?

2 个答案:

答案 0 :(得分:6)

打电话给UB:

Base* base = new Derived;
delete base; // UB here if ~Base is not virtual.

除非Base的析构函数为virtual

  

5.3.5 / 3删除

     

在第一个备选(删除对象)中,如果操作数的静态类型与其动态类型不同,则静态类型应为操作数的动态类型的基类,静态类型应具有虚拟析构函数或者行为未定义。在第二种方法(删除数组)中,如果要删除的对象的动态类型与其静态类型不同,则行为是未定义的.73)

在您的情况下,“操作数的静态类型”为ExtraData,“其动态类型”为BarDataBooData。所以它们是不同的,静态类型ExtraData必须有一个虚拟析构函数。

答案 1 :(得分:2)

执行delete myExtradata;时,删除必须知道如何为删除的对象调用正确的析构函数。为了使其以多态方式工作,ExtraData需要有一个虚拟析构函数。

这不仅需要指针,但在这种特定情况下,我确信std::string中的BarData内部至少有一个指针。