Reputation: 20658
#include<iostream>
using namespace std;
class A
{
public:
int i;
A() {cout<<"A()"<<endl;}
~A() {cout<<"~A()"<<endl;}
};
class B:public A
{
public:
int j;
B(): j(10)
{
this->i=20;
this->~A();
}
};
int main()
{
B abc;
cout<<"i="<<abc.i<<" j="<<abc.j<<endl;
}//main
Two questions:
Is there a way to have an initialization list for A in B's constructor? Something like this:
class B:public A
{
B(): j(10), A():i(20) {}
};
Upvotes: 1
Views: 1032
Reputation: 247999
@Nav: no, your understanding of "destroyed" is just wrong. When an object's destructor is called, the object is destroyed. You seem to believe that the memory it resided in evaporates entirely, but that never happens. The object no longer exists, but some garbage data is typically left over by the object, and if you're willing to break the rules of C++ and invoke undefined behavior, then you can read those leftover bytes, and they'll look like the object, and because there are no runtime checks on whether you're accessing a valid object, you can often treat them as an object. Which you do.
It's illegal, it's undefined behavior, but in practice it often works.
Once again, a destructor does not physically vaporize the memory. Your RAM still has the same capacity after a destructor has executed. Conceptually, the object no longer exists once the destructor has run. But the data it contained is still there in memory.
Upvotes: 4
Reputation: 1847
If you call ~SomeClass() yourself, explicitly, the destructor function will be called. Which leaves the object (in this case, the base class part of the object) in a destroyed state.
Since the destructor is not virtual, the destructor of derived classes will not be called, but base classes of SomeClass will be destroyed too.
Trying to find out if A is really destroyed by just using the i member, is not a good test. In fact, you can't test this, since using the object results in undefined behavour. It may work, or it may not (in your case, it probably will print "i=20 j=10", but i is already destroyed).
Upvotes: 2
Reputation: 1472
In the code that you are giving, you are indeed destroying the base class and as such i
. Calling a destructor and then using the dead object is undefined behavior - it may work or it may crash.
Should i
was something that is more complex that an int
(for example a vector
), trying to do anything with that would probably result in a crash.
Upvotes: 2
Reputation: 89169
For point:
For point 1) on Wikipedia:
having no virtual destructor, while deleting an instance of class B will correctly call destructors for both B and A if the object is deleted as an instance of B, an instance of B deleted via a pointer to its base class A will produce undefined behaviour.
Example (for point 2):
B(): A(), j(10) {}
or
B(): A() {j = 10;}
Upvotes: 3
Reputation: 38173
class A()
constructor in the initialize list of B's constructor, like this:B(): A( .. ), ...
A* a = new B();
//..
delete a;
will not call B's destructor unless class A
destructor is virtual. That's why STL containers should not be derived - theirs destructors are not virtual.
Upvotes: 5
Reputation: 73443
Destructor is like any other normal function which you can call (but you should never do it unless you use a placement new). When you call delete
on a object two things happen: Destructor is called for cleanup and then operator delete
is called to release the memory allocated for the object. Here the second step is not happening.
No, you can not call it like that. What you can do is some thing like this:
class A { public: A(int n) : i(n){} };
class B : public A { public: B() : A(20), j(10){} };
Upvotes: 5
Reputation: 444
1) Destructor calling order in C++ is reverse order of the constructor calling order. So first derived class object get destroy and then base class object.
2) No.
Upvotes: 2