Inner class destructor is called after Base class destructor - c++

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

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.

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

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.

Related

Unusual behavior with C++ vectors

struct Base{
int hp = 1000;
virtual ~Base()
{
std::cout << "Base destructor\n";
}
};
struct Child : Base {
int hp = 100;
virtual ~Child()
{
std::cout << "Child destructor\n";
}
};
int main()
{
std::vector<Base*>vct;
for(int x=0;x<25;x++)
{
vct.push_back(new Child);
}
std::cout << vct[3]->hp;
return 0;
}
I have written this program, which creates 25 objects of type Child, yet when run, both the destructors of the child and base class are called, which would imply that the 'new child' call would create an instance of both the child, and the base class. Why?
Furthermore, trying to access the int "hp" of any of the members of the vector, always returns 1000, not 100, which indicates that all the vector members are of type Base, not of type Child.
So in short, what do I need to do to 1. only create Child objects, not Base(even having the Base class as an abstract class still, somehow, seems to create objects of it) 2. Have all the members/elements of the vector to be of the child class, when the type of the vector is Base*
This is exactly how C++ inheritance works. Even if you didn't explicitly define a constructor, the parent class's default constructor still runs. In this case, the default constructors are mostly a no-op save for the member initialization of hp in both.
Both Child destructor and Base destructor get printed because you declared your destructor (correctly) as virtual. However, you aren't explicitly deleting any instance of objects you are allocating via new, so I'm not sure how you are seeing any print statements at all.
The hp in Child shadows the hp in Base, but member variables are not virtual. So when you access hp via Base class pointer, you get the Base class member. If you want to have the derived class access to hp, mark hp as protected in Base, and set in constructor in derived. In you case, everything is a struct, so all members are already public.
struct Base{
int hp = 1000;
virtual ~Base()
{
std::cout << "Base destructor\n";
}
};
struct Child : Base {
Child()
{
hp = 100; // Base constructor has already run, so we override here
}
virtual ~Child()
{
std::cout << "Child destructor\n";
}
};
int main()
{
std::vector<Base*>vct;
for(int x=0;x<25;x++)
{
vct.push_back(new Child);
}
std::cout << vct[3]->hp;
// let's delete explicitly and avoid the leak.
for(int x=0;x<25;x++)
{
delete vec[x];
vec[x] = nullptr; // not necessary, but is a good practice
}
return 0;
}

Usage of Derived class with the std::shared_ptr of Base class

Is the following approach good?
class TA { };
class TB : TA { };
std::shared_ptr<TA> spta;
spta.reset(new TB);
There's one problem with the code shown, TB must inherit publicly from TA. You have a shared_ptr<TA>, so the pointer you want to store in it must be convertible to TA, but with private inheritance, the base is inaccessible so your code will not compile.
class TA { };
class TB : public TA { };
Beyond this, the code has no errors and is well-behaved. Typically, when you perform polymorphic deletion of a derived class instance through a base class pointer, you need the base class' destructor to be virtual so the derived class destructor is called, but in case of shared_ptr this is not necessary. shared_ptr::reset is a function template that'll accept any Y* that is convertible to the managed pointer type. The same is true for shared_ptr's constructor template.
That being said, you should prefer making the base class' destructor virtual, especially if the classes involved have other virtual functions.
No, it is not for TA is private.
Moreover, as suggested in the comments, the destructor of the base class ought to be virtual. It is usually a good practice, for you cannot guarantee that instances of your classes will be used only with shared pointers.
To have it working, you must at least modify these lines:
class TA { };
class TB : TA { };
As it follows:
class TA { virtual ~TA() { } };
class TB : public TA { };
Those ones are good as the following example is good:
class TA { virtual ~TA() { } };
class TB : public TA { };
TA *spta = nullptr;
spta = new TB;
It mainly depends on what good means for you. It's legal, at least.
This is not an answer to the question, it is an attempt to clear up any confusion about shared_ptr's seemingly magical ability to avoid the use of a virtual destructor.
Here's a little demo program:
#include <iostream>
#include <memory>
struct A {
~A() { std::cout << __func__ << std::endl; }
void foo() { do_foo(); }
protected:
virtual void do_foo() {
std::cout << "A::" << __func__ << std::endl;
}
};
struct B : A {
~B() { std::cout << __func__ << std::endl; }
virtual void do_foo() override {
std::cout << "B::" << __func__ << " ";
A::do_foo();
}
};
using namespace std;
auto main() -> int
{
std::shared_ptr<A> p = std::make_shared<A>();
p->foo();
p = std::make_unique<B>();
p->foo();
cout << "deleting B:" << endl;
return 0;
}
expected output:
A::do_foo
~A
B::do_foo A::do_foo
deleting B:
~B
~A
Notice that the correct destructor was called when the B was destroyed at the end of main().

Force sub-classes to implement and call (once) a method

I am looking for a way to create a method that has to be implemented by every subclass. I also want the subclass to call this method on construction.
It should not be possible to call this method again after class construction..
#include <iostream>
class Base {
public:
Base() {init();}
private:
virtual void init() = 0;
};
class DerivedA : public Base {
public:
DerivedA() {}
private:
virtual void init() { std::cout << "Hello, I am A.";}
};
class DerivedB : public Base{
public:
DerivedB() {}
private:
virtual void init() {std::cout << "Hello, I am B.";}
};
int main(){
DerivedA a;
DerivedB b;
return 0;
}
This is an example, but it is not valid, because it calls a pure virtual method in constructor. Of course I can add init() in every subclass-constructor, but then it can be forgotten on new subclasses.
What is the C++ way of doing this?
The C++ way is to not do this. Init functions are bad. Simply use the constructors.
AFAIK, it is very dangerous to call virtual functions in constructors. Here is a simple example. I slightly modified your code to have init method also implemented in Base class :
#include <iostream>
#include <exception>
class Base {
protected:
Base() {init() ; }
virtual void init() {
std::cout << "Init base" << std::endl;
}
public:
void callinit() {
init();
}
};
class DerivedA : public Base {
public:
DerivedA() {}
protected:
virtual void init() { std::cout << "Hello, I am A."<< std::endl;}
};
class DerivedB : public Base{
public:
DerivedB() {}
protected:
virtual void init() {std::cout << "Hello, I am B."<< std::endl;}
};
int main(){
DerivedA a;
DerivedB b;
a.callinit();
b.callinit();
return 0;
}
and the output is :
Init base
Init base
Hello, I am A.
Hello, I am B.
What can we conclude of that :
once the object is constructed, all is fine and when we call init method we normaly get the correct implementation from derived class
but in constructor, the order is :
call Base constructor
call init method from Base object (since derived object in not still constructed)
call DerivedX constructor
So the method is always the one from Base which is definitively not what you expected.
As the other poster said, you should probably stay away from this, but the easiest example would be to make a public, non-virtual interface method on Base called Init() that must be called after the object is constructed. That method can call a pure-virtual "DoInit" method on the derived classes, and track whether or not it has been called yet with an internal flag.
I don't recommend this, but it will work.
class Base
{
public:
void Init()
{
if(!initialized)
{
DoInit();
initialized = true;
}
}
protected:
virtual void DoInit() = 0; // derived classes need to implement this
private:
bool initialized {false};
};
I faced similar problem and could not find a simple solution. I had to make the initialization in a separate class. An object of this class can be passed to Base/Derive constructors, or this class can be a template parameter.
class Initializer {
. . .
}
class Base {
public:
Base(Initializer* initializer) {
// Get members from initializer
}
}
Or:
template<Initializer TInitializer>
class Base<TInitializer> {
public:
Base() {
TInitializer initializer;
// Get members from initializer
}
}
Sorry, I did not write in C++ too long, so I could prevent some syntax errors.
C++11's call_once gets you most of the way, but it has costs.
The class will not be movable nor copyable.
You must add an extra line in every function that requires the initialization.
It does not prevent the method from being called more than once, but that is easy to add.
#include <iostream>
#include <mutex>
struct Base {
Base() {
std::cout << "Base ctor" << std::endl;
}
void sampleFunction1() {
// this line must be at the start of every function that needs the initialization
std::call_once(initedFlag, &Base::v_init, this);
std::cout << "Base::sampleFunction1" << std::endl;
}
void sampleFunction2() {
// this line must be at the start of every function that needs the initialization
std::call_once(initedFlag, &Base::v_init, this);
std::cout << "Base::sampleFunction2" << std::endl;
}
private:
virtual void v_init() = 0;
std::once_flag initedFlag;
};
Notice that the Derived class has nothing special, except that it provides v_init.
struct Derived : Base {
Derived() {
std::cout << "Derived ctor" << std::endl;
}
private:
void v_init() override {
std::cout << "Derived::v_init" << std::endl;
}
};
Demo code
int main(int argc, const char * argv[]) {
Derived d1;
Derived d2;
std::cout << "Calling d1" << std::endl;
d1.sampleFunction1();
d1.sampleFunction2();
std::cout << "Calling d2" << std::endl;
d2.sampleFunction2();
d2.sampleFunction1();
return 0;
}
Output: Notice that v_init will be called which ever sample function is called first and is not called in the ctors.
Base ctor
Derived ctor
Base ctor
Derived ctor
Calling d1
Derived::v_init
Base::sampleFunction1
Base::sampleFunction2
Calling d2
Derived::v_init
Base::sampleFunction2
Base::sampleFunction1

Destructor concept in c++

please go through my below code:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
class ClassA
{
protected:
int width, height;
public:
void set_values(int x, int y)
{
width = x;
height = y;
}
virtual int area()
{
return 100;
}
~ClassA()
{
cout << "base class destructor called" << endl;
}
};
class ClassB : public ClassA
{
public :
int area()
{
return (width * height);
}
~ClassB()
{
cout << "derived class destructor called" << endl;
}
};
int main()
{
ClassA *Ptr = new ClassB;
Ptr->set_values(10, 20);
cout << Ptr->area() << endl;
delete Ptr;
return 0;
}
In the above code the pointer contain the address of derived class object so it should call derived class destructor along with base class destructor when i delete the pointer,but why it is calling only base class destructor. if i made base class destructor as virtual then it is calling both derived class and base class destructor why?. and in virtual functions case both the base and derived class has the same function name so compiler resolve the one which is most derived in the derived class but here the destructor won't have same name then how the compiler resolves which one it has to call during run time.please explain me how
You should make the destructor of your base class virtual in order for polymorphic destruction to work properly:
class ClassA
{
// ...
virtual ~ClassA()
// ^^^^^^^
// Add this!
{
cout << "base class destructor called" << endl;
}
};
If you do not do that, you get Undefined Behavior when doing delete Ptr.
if i made base class destructor as virtual then it is calling both derived class and base class destructor why?
This is part of the regular object destruction sequence. When you destroy an object, the destructor of that object's class gets called first, then the destructors of all the non-static class members of that object (in inverse order of declaration), then the destructors of all its base classes.
Thus, virtual dispatch is correctly performed here (if you make your base class destructor virtual, of course), in the sense that the first destructor that gets invoked is the destructor of the actual run-time type of your object (ClassB). After that, the destructor of the base class ClassA gets invoked as well as part of the normal destruction process.
but here the destructor won't have same name then how the compiler resolves which one it has to call during run time
Destructors are special member functions. Each class can have only one destructor, so their name (which must be identical to the name of the class, with the prepended ~ character) is irrelevant. The compiler knows which function is a destructor.
Because your Base class destructor should be virtual.
That's actually undefined behavior because ~ClassA() is not virtual, so anything can happen.
ClassA *Ptr = new ClassB;
///....
delete Ptr;
You need to mark your destructors as virtual. Otherwise the compiler doesn't know to call the most-derived destructor.
virtual ~ClassA()
{
cout << "base class destructor called" << endl;
}

Scope of pure virtual functions during derived class destruction - In C++

During destruction of the derived class object, i first hit the derived class destructor and then the base class destructor (which is as expected). But i was curious to find out - at what point does the functions of the derived class go out of scope (are destroyed).
Does it happen as soon as the control leaves the derived class destructor and goes toward the base? Or does it happen once we done with the base class destructor also.
Thanks
Once the destructor of the most derived class finishes, the dynamic type of the object can be considered that of the next less-derived-type. That is, a call to a virtual method in the base destructor will find that the final overrider at that point in time is at base level. (The opposite occurs during construction)
struct base {
base() { std::cout << type() << std::endl; }
virtual ~base() { std::cout << type() << std::endl; }
virtual std::string type() const {
return "base";
}
};
struct derived : base {
virtual std::string type() const {
return "derived";
}
};
int main() {
base *p = new derived;
std::cout << p->type() << std::endl;
delete p;
}
// output:
// base
// derived
// base
Functions don't get destroyed.
Virtual functions however get their entry in the v-table erased as soon as the derived destructor finishes so you can't call derived virtual functions from the base d'tor.