Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of destruction parent and child

Why does C++ destructs the Parent class before the Child class? Would it not be more logical for an object when its goes out of scope to first destruct the shared_ptrs and then destruct itself? In my workflow this causes a problem, because my Parent class is managing an interface that the Child classes use.

#include <iostream>
#include <memory>

class Child;

class Parent
{
    public:
        Parent() :
            child(std::make_shared<Child>())
        { 
            std::cout << "Constructing parent" << std::endl;
        }
        ~Parent() { std::cout << "Destructing parent" << std::endl; }
    private:
        std::shared_ptr<Child> child;
};

class Child
{
    public:
        Child()
        { 
            std::cout << "Constructing child" << std::endl;
        }
        ~Child() { std::cout << "Destructing child" << std::endl; }
};

int main()
{
    Parent parent;
    return 0;
}

EDIT
Based on the comments, I feel that my problem needs more explanation. My child classes are all allocated on std::shared_ptr, which get released when the parent goes out of scope. My main program is a CUDA program, and the parent has access to the GPU device. If the parent gets deleted, I no longer have access to the GPU. The destructors of the children, however, need to deallocate their GPU memory, and I therefore, want to have this action taken before parent goes out scope. But that means I manually have to delete the smart pointers, which in my view, defeats their purpose a bit.

like image 339
Chiel Avatar asked Feb 28 '18 10:02

Chiel


Video Answer


2 Answers

The destruction order is defined as (emphasis mine):

For both user-defined or implicitly-defined destructors, after the body of the destructor is executed, the compiler calls the destructors for all non-static non-variant members of the class, in reverse order of declaration, then it calls the destructors of all direct non-virtual base classes in reverse order of construction (which in turn call the destructors of their members and their base classes, etc), and then, if this object is of most-derived class, it calls the destructors of all virtual bases.

A good justification is that the destructor of Parent may need access to its members for the purpose of releasing resources, not every object is self-contained.

like image 177
Rotem Avatar answered Sep 28 '22 11:09

Rotem


Would it not be more logical for an object when its goes out of scope to first destruct the shared_ptrs and then destruct itself?

Not really, the destructor of Parent may need to access some members to do some kind of cleanup, so they need to be accessible and alive inside the constructor body. If you need to destroy the Child first you can always do it manually:

~Parent() { 
  child.reset();
  // do the rest ...
}
like image 24
amc176 Avatar answered Sep 28 '22 11:09

amc176