Coda
Coda

Reputation: 13

Inner class destructor is called after Base class destructor

i have a basic and simply question.

I have this scenario:

#include <iostream>
using namespace std;

class Inner1
{
public:
    ~Inner1() {cout << "Inner1 Des\n";};
};

class Inner2
{
public:
    ~Inner2() {cout << "Inner2 Des\n";};
};

class Base
{
public:
    ~Base() {cout << "Base Des\n";};

    Inner1 inner1;
    Inner2 inner2;
};

int main() {
    Base base;
    return 0;
}

And my console tells me now this:

Base destructor called
Inner2 destructor called
Inner1 destructor called

Is this the normal behavior? Because the functionality for some functions
is already destroyed in my Base Class destructor and the Inner classes rely on them.

Not recommended workaround:

Just add a "Destroyer" class with object at the first position:

[...]
class Base
    {
    public:
        ~Base() {cout << "Base Des\n";};

        class Destroyer
        {
             ~Destroyer()
             {
                 //Put the stuff here because this destr will be called last
                 cout << "Destroyer Des\n";
             }
        } _destroyer;
        Inner1 inner1;
[...]

Thank you for your help

Upvotes: 1

Views: 2480

Answers (3)

ravi
ravi

Reputation: 10733

Class members are constructed in a sequence they are defined in class. That means,

class Demonstration
{
    XClass x;
    YClass y;
};

In above example, x will be constructed before y. As destruction happens in reverse order of construction, y will always be destructed before x.

Upvotes: 0

eerorika
eerorika

Reputation: 238321

Is this the normal behavior?

Yes. Subobject destructors are called by the destructor of the container class. In particular, the subobjects will be destroyed after the body of the container classes destructor has been executed.

Because the functionality for some functions is already destroyed in my Base Class destructor and the Inner classes rely on them.

That's only a problem if the inner classes [sic] destructors rely on the Base instance that contains them. In that case either Base should not contain them as members, or their destructor should not depend on Base.

Upvotes: 1

Loki Astari
Loki Astari

Reputation: 264381

Using this code:

#include <iostream>

class Base
{
    public:
        class Sub1
        {
            public:
                Sub1()
                {
                    std::cout << "Base::Sub1::Constructed\n";
                }
                ~Sub1()
                {
                    std::cout << "Base::Sub1::Destroyed\n";
                }
        };
        class Sub2
        {
            public:
                Sub2()
                {
                    std::cout << "Base::Sub2::Constructed\n";
                }
                ~Sub2()
                {
                    std::cout << "Base::Sub2::Destroyed\n";
                }
        };


        Sub1    sub1;
        Sub2    sub2;
        Base()
        {
            std::cout << "Base::Constructed\n";
        }
        ~Base()
        {
            std::cout << "Base::Destroyed\n";
        }
};

int main()
{
    Base    base;
}

I get (added comments manually)

> ./a.out
// Build all members first in the order they are declared.
Base::Sub1::Constructed
Base::Sub2::Constructed
// Call the constructor of the object
Base::Constructed

// Destruction happens in revers.
// Calls the destructor code to handle all local resources
Base::Destroyed
// Then destroy all members in reverse order of declaration
Base::Sub2::Destroyed
Base::Sub1::Destroyed

Upvotes: 1

Related Questions