Search code examples
c++polymorphismunique-ptr

sequence of destructors when using unique_ptr to base class


I am experimenting with std::unique_ptr and class inheritance (i.e. polymorphism somehow). The code I am running is the following:

#include<iostream>
#include<memory>

class polygon {
    public:
    int side;
    polygon(int i): side(i) {std::cout<<"polygon created"<<std::endl;}
    virtual int perimeter() = 0;
    ~polygon() {std::cout<<"polygon destroyed"<<std::endl;}
};
class triangle : public polygon {
    public:
    triangle(int i): polygon::polygon{i} {std::cout<<"triangle created"<<std::endl;}
    int perimeter() { return side*3; }
    ~triangle() {std::cout<<"triangle destroyed"<<std::endl;}
};
class square : public polygon {
    public:
    square(int i): polygon::polygon{i} {std::cout<<"square created"<<std::endl;}
    int perimeter() { return side*4; }
    ~square() {std::cout<<"square destroyed"<<std::endl;}
};

int main() {
    std::unique_ptr<polygon> pp = std::make_unique<square>(5); // (1)
    std::cout << pp->perimeter() << std::endl;

    pp = std::make_unique<triangle>(4); // (2)
    std::cout << pp->perimeter() << std::endl;

    return 0;
}

I can see that destructors are invoked in reverse order with respect to constructors, and that applies also to base class-derived class sequences of constructors and destructors.

However, only the polygon destructors are invoked, i.e. when assigning (I guess because the first std::make_unique<square> is destroyed, or when returning 0. Does that mean that when destroying a base class std::unique_ptr, the memory allocated to the derived class objects in (1) and (2) is leaked?


Solution

  • Yes, in C++ you have to explicitly mark your destructor virtual in the base class, if you delete through a pointer to the base class (as you do). So change the destructor of polygon to:

    virtual ~polygon() {std::cout<<"polygon destroyed"<<std::endl;}
    

    PS: Make your perimeter function const.