Alejandro Garcia Ruiz
Alejandro Garcia Ruiz

Reputation: 13

Virtual destructor for non pointer member variables

I have a question regarding virtual destructors. I know that if a variable pointer is polymorphic it is neccesary to create a virtual destructor, but if I don't need to do any destruction specific code is it necessary?

For example, the following code:

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 is created from outside the struct, it can be either via new BarData() or via new BooData(). Would BarData and BooData need a virtual destructor. Or since they don't have member pointer it's okay?

Upvotes: 1

Views: 488

Answers (2)

Jarod42
Jarod42

Reputation: 217085

It would be UB to call:

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

unless destructor of Base is virtual.

5.3.5/3 Delete

In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand’s dynamic type and the static type shall have a virtual destructor or the behavior is undefined. In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.73)

In your case, "static type of the operand" is ExtraData and "its dynamic type" is either BarData or BooData. So they are different, and the static type ExtraData must have a virtual destructor.

Upvotes: 6

Bo Persson
Bo Persson

Reputation: 92211

When you do delete myExtradata; the delete will have to know how to call the correct destructor for the object that is deleted. For that to work polymorphically, ExtraData needs to have a virtual destructor.

It's not only needed for pointers, but in this specific case I'm sure std::string in BarData has at least one pointer internally.

Upvotes: 2

Related Questions