0

Having a simple class hierarchy, I instantiate from derived and store it as a base class variable. At the end of the scope, destructor of base is called twice. Making base destructor virtual does not work. It is unwanted in many cases. What is the reason of this bizarre behaviour and what is the correct way of doing this?

Here is an example erroneous case:

#include <iostream>

class Base{
private:
    int* a;

public:
    Base() {
        std::cout << "Base constructor" << std::endl;
        a = new int{6};
    }

    virtual ~Base(){
        std::cout << "Base destructor" << std::endl;
        delete a;
    }
};

class Derived: public Base {
private:
    int* b;

public:
    Derived() {
        std::cout << "Derived constructor" << std::endl;
        b = new int{7};
    }

    ~Derived(){
        std::cout << "Derived destructor" << std::endl;
        delete b;
    }
};

int main() {
//    Base b = Base();  // ok
//    Derived b = Derived();  // ok

    Base b = Derived();  // double free

//    Base b;  // even worse 
//    b = Derived();

//    Base *b;  // ok, but not desired
//    b = new Derived();
//    delete b;

    return 0;
}

I use g++ (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0 compiler. Both -std=c++20 and -std=c++11 are same for this example.

tugaykansu
  • 29
  • 4
  • Polymorhism only works with pointers and references. `Base b = Derived()` will *slice* the `Derived` object, leaving only the `Base` part. – Some programmer dude Dec 01 '22 at 11:38
  • On another couple of notes, `Base b = Base();` is exactly equal to `Base b;`. And `Base *b; b = new Derived();` could be written as `Base *b = new Derived;` – Some programmer dude Dec 01 '22 at 11:39
  • 1
    Apart from the incorrect polymorphism, the actual reason for your error and the double free, is the failure of your `Base` and `Derived` classes to follow the rule of three. See duplicate for details. – john Dec 01 '22 at 11:39
  • 2
    In fact I'd say a bit more and say that both errors are caused by you not properly appreciating the *value semantics* that C++ uses. Perhaps you are used to another language which does not have value semantics. – john Dec 01 '22 at 11:40

0 Answers0