-2

I was extremely surprised to see the following work. If you have a set of classes that extend each other, and you create a container for them using the base class pointer, how is it able to properly call all associated destructors?

#include <iostream>
#include <string>
#include <vector>

class A {
    public:
        A(){
            std::cout << "Constructor A is called\n";    
        }
        virtual ~A(){
            std::cout << "Destructor A is called\n";    
        }
};

class B {
    public:
        B(){
            std::cout << "Constructor B is called\n";    
        }
        virtual ~B(){
            std::cout << "Destructor B is called\n";    
        }
};

class C : public A, public B {
    public:
        C(){
            std::cout << "Constructor C is called\n";    
        }
        ~C(){
            std::cout << "Destructor C is called\n";    
        }
};

int main()
{
    std::vector<A*> objects;
    C *c = new C();
    objects.push_back(c);


    for(size_t i = 0; i < objects.size(); i++){
        delete objects[i];
    }
}

I would have expected only A's destructor to be called..!

Constructor A is called
Constructor B is called
Constructor C is called
Destructor C is called
Destructor B is called
Destructor A is called
  • 4
    It works because the destructors are declared `virtual`. To learn more about this, consult your [favourite C++ textbook](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Paul Sanders Jun 17 '20 at 23:30
  • 4
    It depends on the question. With something as fundamental as this it doesn't help to spell it out on a Q&A site such as SO, IMO, you need to do some studying. – Paul Sanders Jun 17 '20 at 23:34
  • I completely disagree. While it is in the nature of (most..) programmers to enjoy orderliness and eliminate redundancy, this website is actually more powerful based on how diverse a question is asked. It is better that there are 20 questions worded differently for the same problem, because 20 people will ask it in 20 ways, and Google and search engines will more easily find it. – terratermatwoa Jun 17 '20 at 23:37
  • Diversity of simple and basic questions may be useful for other languages that can be learned by example but C++ is not such a language. As a C++ programmer, you essentially are required to inform yourself about the correct usage and safety of the language from reliable documentation. Individual answers here on StackOverflow cannot address gaps in a learner's fundamental understanding of the language. This is also explained in the [definitive C++ book list](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) mentioned above. – alter_igel Jun 18 '20 at 00:27
  • @alterigel Surely 90% of SO questions should be removed, then. You can probably look to the right in "Related" and see a few questions as basic as "what is a pointer." – terratermatwoa Jun 22 '20 at 14:27

1 Answers1

3

When A::~A() is invoked through a pointer/reference, it is called virtually, because A::~A() is declared virtual. This winds up invoking C::~C() instead, since the actual object being deleted is of type C.

C's destructor implicitly calls the A and B destructors (but statically, not virtually).

Note that a method with the same signature as an inherited virtual method is itself virtual and overrides the inherited method. This means C::~C() is also virtual, despite not being explicitly declared so.

cdhowie
  • 158,093
  • 24
  • 286
  • 300