Can anyone explain to me the constructor calls, in the following code.
How is the constructor of abstract class called, when there exist no object for it but only a pointer to the derived class. Is an instance of it created to hold the vtable ?
#include <iostream>
using namespace std;
class pure_virtual {
public:
pure_virtual() {
cout << "Virtul class constructor called !" << endl;
}
virtual void show()=0;
};
class inherit: public pure_virtual {
public:
inherit() {
cout << "Derived class constructor called !" << endl;
}
void show() {
cout <<"stub";
}
};
main() {
pure_virtual *ptr;
inherit temp;
ptr = &temp;
ptr->show();
}
The constructor of the pure_virtual class is called when the constructor of inherit is called. So, when the line inherit temp; is executed, the constructor of the object is being called, because it is a derived class. Then the base class constructor is called first.
So in your case the output will be
Virtul class constructor called !
Derived class constructor called !
and because the void show() is virtual, the correct function is called, which is that of the inherit class.
Related
Why the base class constructor is not called twice in the following code?
#include<iostream>
using namespace std;
class base{
public:
base(){cout << "In the Base Constructor\n"; }
~base(){
cout << "In Base Destructor\n";
}
};
class derived: public base{
public:
derived(){cout << "In Derived Constructor\n";}
~derived(){
cout << "In Derived Destructor\n";
}
};
int main(){
base *bptr;
derived d;
}
output:
In the Base Constructor
In Derived Constructor
In Derived Destructor
In Base Destructor
It must be because of the pointer. But I am not clear why?
This is a pointer to something.
base *bptr;
It is not initialised.
It does not point to anything clean.
It especially does not point to any already created object.
Even if it did, that would not cause any constructor to be executed.
If there would be any object the pointer points to, then the creation of that object would have happened elsewhere, earlier.
This defines an object:
derived d;
This is what causes the observed execution of constructors.
I create a object of derived class and a base class point for it ,
and then I use the dynamic_cast convert base class point to derived class point .
I delete the derived class point , but the program calls the derived destructor and the base destructor. Why does the program call the base destructor? After all, the base destructor isn't a virtual function....
#include<iostream>
#include<stdlib.h>
using namespace std;
class con {
private:
double num;
public:
con() {
num = 0;
cout << "default..." << endl;
}
void getnum() {
cout << num << endl;
}
};
class base {
public:
virtual void A() {
cout << "it is base A" << endl;
}
void B() {
cout << "it is base B" << endl;
}
~base() {
cout << "it is base decon" << endl;
}
};
class child : public base {
public:
void A() {
cout << "it is child A" << endl;
}
void B() {
cout << "it is child B" << endl;
}
~child() {
cout << "it is child decon" << endl;
}
};
int main(int argc, char** argv) {
base* b = new child();
child* c = dynamic_cast<child*>(b);
delete c; //the program print "it is child decon" "it is base decon"
getchar();
return 0;
}
Case 1: If you delete a pointer derived class, it always calls the destructor of the derived class first, then the destructor of the base class.
Case 2: If you delete a pointer to the base class of a derived class with a non-virtual base class destructor, it doesn't know about the derived class so it just deletes the base class.
Case 3: If you delete a pointer to the base class of a derived class with a virtual base class destructor, it uses virtual dispatch to the destructor of the derived class, then calls the destructor of the base class.
Case 2 is bad. It can cause resource leaks, etc. It should be avoided by always declaring destructors virtual in classes that are intended to be base classes.
Your example illustrates case 1.
If you want to see case 2 in action try delete b rather than delete c in your example.
Destructors in C++ don't "overload" as such; they chain up. When you say
{
child c;
}
then at the closing brace the compiler will insert a call to ~child(), which will in turn call ~base() (and the destructors of other base classes, if you had them). This is essential to avoid memory leaks -- otherwise how would base's members be destroyed? Note that this doesn't require the base destructor to be virtual.
This works the same way when you manually destroy something with delete:
child* c = new child{};
delete c; // runs ~child(), which calls ~base()
again, this doesn't require the destructor to be virtual.
What a virtual destructor does do is allow you to destroy a variable with dynamic type child using a pointer to a base, i.e.
child* c = new child{}
base* b = c;
delete b; // Will call ~child() if destructor is virtual, otherwise ~base()
Im reading this article on constructors for c++
We recommend that you be careful when you call virtual functions in
constructors. Because the base class constructor is always invoked
before the derived class constructor, the function that's called in
the base constructor is the base class version, not the derived class
version. In the following example, constructing a DerivedClass causes
the BaseClass implementation of print_it() to execute before the
DerivedClass constructor causes the DerivedClass implementation of
print_it() to execute:
the example:
class BaseClass {
public:
BaseClass() {
print_it();
}
virtual void print_it() {
cout << "BaseClass print_it" << endl;
}
};
class DerivedClass : public BaseClass {
public:
DerivedClass() {
print_it();
}
virtual void print_it() {
cout << "Derived Class print_it" << endl;
}
};
int main() {
DerivedClass dc;
}
Here's the output:
BaseClass print_it
Derived Class print_it
I tried this code and the output is as stated above.
However I also tried the same example without the virtual keyword:
class BaseClass {
public:
BaseClass() {
print_it();
}
void print_it() {
cout << "BaseClass print_it" << endl;
}
};
class DerivedClass : public BaseClass {
public:
DerivedClass() {
print_it();
}
void print_it() {
cout << "Derived Class print_it" << endl;
}
};
int main() {
DerivedClass dc;
}
and got the same result.
So what is the difference and what is the danger they are warning for?
#marked as duplicate:
This question is different as the consturctors both call the virtual method instead of one constructor calling the virtual method.
There is no difference. That's the danger.
If you did not know better then you might expect this instead:
Derived Class print_it
Derived Class print_it
The expectation is there because if you call the virtual print_it() from functions in Base, polymorphism means you'll usually get the Derived version instead.
But, when you write it in the Base constructor, the Base part of the object is still under construction, and the "dynamic type" of the object under construction is still Base, not Derived. So you do not get the usual polymorphic behaviour.
The article is warning you about this fact.
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.
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;
}