1

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

Coda
  • 13
  • 4
  • You should show us the code that generates those messages. Otherwise we are just guessing at the behavior. – Martin York Apr 27 '16 at 07:06
  • That's not a sub class but an inner class. Subclassing refers to inheritation. _Then_ the dtors of the derived classes would be called before the base class destructor. – Albjenow Apr 27 '16 at 07:08
  • Those messages are just standard cout messages which i added to every destructor, nothing special. Its just about this scenario and standard c++ i think it has nothing todo with my other code. – Coda Apr 27 '16 at 07:08
  • please provide [MCVE](http://stackoverflow.com/help/mcve) code – Undefined Behaviour Apr 27 '16 at 07:10
  • @Albjenow This says that this is normal for inner classes? – Coda Apr 27 '16 at 07:10
  • Since you might want to use the inner object within the destructor of the containing class, it is not possible to delete said object before the surrounding one has finished with it. – Albjenow Apr 27 '16 at 07:14
  • @Albjenow No i mean that i have a library initialized within the constructor and the inner classes use them and after that i have to make a clean exit with the library. – Coda Apr 27 '16 at 07:19
  • Yes, this is normal behavior. – MikeMB Apr 27 '16 at 07:29
  • Btw. It is a little confusing, that you call your class Base, when it isn't actually a Baseclass. – MikeMB Apr 27 '16 at 07:31

3 Answers3

1

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
Martin York
  • 257,169
  • 86
  • 333
  • 562
  • Yeah, thats my problem. Could you give me any advice how to handle this situation? – Coda Apr 27 '16 at 07:16
  • 2
    @Coda: What's the problem. This is how C++ is defined. – Martin York Apr 27 '16 at 07:17
  • i know but what should i can do about this "Because the functionality for some functions is already destroyed in my Base Class destructor and the Inner classes rely on them.". – Coda Apr 27 '16 at 07:20
  • Move the functionality form `SubX::~SubX` to some function, say `SubX::cleanUp` that is called within `Base::~Base`. – Albjenow Apr 27 '16 at 07:22
  • 2
    `inner classes` Please use the correct terminology `members`. You are going to have to change your design (you can't change this behavior). But your current description is too vague to provide any specific advice. – Martin York Apr 27 '16 at 07:23
  • Youre right thank you, i will add some bools and add delete &member; for every member class. – Coda Apr 27 '16 at 07:29
1

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.

eerorika
  • 232,697
  • 12
  • 197
  • 326
0

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.

ravi
  • 10,994
  • 1
  • 18
  • 36