I have the following program:
#include<iostream>
using namespace std;
class A {
protected:
A() { cout << "Executing A()" << endl; }
public:
~A() { cout << "Executing ~A()" << endl; }
};
class B : public A {
public:
B() { cout << "Executing B()" << endl; }
~B() { cout << "Executing ~B()" << endl; }
};
class C : public B {
public:
C() { cout << "Executing C()" << endl; }
~C() { cout << "Executing ~C()" << endl; }
};
void someFunc() {
A a = C();
}
int main() {
someFunc();
return 0;
}
which prints the following:
Why is ~A() called twice?
The destructor for A is called twice because there are two objects that need to be destroyed. By printing something when the copy or move constructor is called you can verify this:
class A {
protected:
A() { cout << "Executing A()" << endl; }
public:
A(const A &) { cout << "Executing A(const A &)" << endl; }
// with recent compilers, you could also try A(A &&)
~A() { cout << "Executing ~A()" << endl; }
};
Output:
Executing A()
Executing B()
Executing C()
Executing A(const A &)
Executing ~C()
Executing ~B()
Executing ~A()
Executing ~A()
Basically, A a = C(); doesn't do what you might think it does. It creates an anonymous C object, and then creates a as an A object, copying from the just-created anonymous object. It does not let a somehow point to a real C object.
A variable declared as A is always an A, never any derived type. To get something to that effect, you would need to use pointers or references.
const A &a = C();
Here, a is not an A object. This creates the same anonymous C object as before, but then makes a a reference to that anonymous object, instead of attempting to create a new A object.
Related
#include <iostream>
using namespace std;
#define debug(x) cout << #x << ": " << (x) << endl;
class Base {
public:
void f() { cout << "Base:f()" << endl; }
~Base() { cout << "Base:~Base()" << endl; }
};
class A : public Base {
public:
~A() { cout << "A:~A()" << endl; }
};
int main() {
{
A a;
static_cast<Base>(a);
}
return 0;
}
In this code
I call the static_cast to covert the A to Base,
the output tells me that it calls the ~Base() twice?
why the static_cast make the destructor be called?
static_cast<Base>(a); constructs a temporary Base, which is copied from a. After the full expression the temporary gets destroyed, the destructor of Base is called.
After that, when get out of the scope a gets destroyed, the destructor of A and Base are called in order. Note that this has nothing to do with the static_cast.
I am trying to see the effects of calling virtual destructors of classes belonging to a long chain of hierarchy: class A to class E.
Strangely, the destructors do not write anything to the console. I first thought perhaps it was happening because main was exiting too. So, I put all the testing code within a function called test() and invoked from within main() so when test would return, I would see destructor footprints. But, nothing! No "cout" signs on the console show up!
#include <iostream>
using namespace std;
//A constructor cannot be virtual but a destructor can.
class A {
public:
A() {
cout << "A constructor" << endl;
}
virtual ~A() {cout << "A destructor" << endl;}
};
class B :public A {
public:
B() {
cout << "B constructor" << endl;
}
virtual ~B() {cout << "B destructor" << endl;}
};
class C :public B {
public:
C() {
cout << "C constructor" << endl;
}
virtual ~C() {cout << "C destructor" << endl;}
};
class D :public C {
public:
D() {
cout << "D constructor" << endl;
}
~D() {cout << "D destructor" << endl;}
};
class E :public D {
public:
E() {
cout << "E constructor" << endl;
}
~E() {cout << "E destructor" << endl;}
};
void test() {
cout << "Test1 begins..." << endl;
A* a1 = new D();
cout << "Test2 begins..." << endl;
A* a2 = new E();
}
int main() {
test();
return 0;
}
Ummm... you actually leak those.
Every objected created by the new keyword must have an equivilant delete:
void test() {
cout << "Test1 begins..." << endl;
A* a1 = new D();
cout << "Test2 begins..." << endl;
A* a2 = new E();
delete a1;
delete a2;
}
Developers (just in your case) always forgot to delete dynamically allocated objects, so smart pointers were introduce:
void test() {
cout << "Test1 begins..." << endl;
std::unique_ptr<A> a1(new D());
cout << "Test2 begins..." << endl;
std::unique_ptr<A> a2(new E());
}
no need to worry about a leak, as unique_ptr automatically delete their pointee when they get out of scope.
You never delete your raw pointers. Prefer smart pointers to raw ones.
You should add
delete a1;
delete a2;
near the end of your test.
Try also to create some instances of E as an automatic variable (usually on the call stack). For example, insert
E ee;
in between those two delete-s.
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout << "A ctor" << endl;
}
virtual ~A()
{
cout << "A dtor" << endl;
}
virtual void foo() = 0;
};
class B : public A
{
public:
B()
{
cout << "B ctor" << endl;
}
virtual ~B()
{
cout << "B dtor" << endl;
}
virtual void foo()
{
cout <<"B's foo" << endl;
}
};
class C : public A
{
public:
C() {
cout << "C ctor" << endl;
}
virtual ~C()
{
cout << "C dtor" << endl;
}
virtual void foo() {cout << "C's foo" << endl;
}
};
int main ()
{
C *ptr = new C[1];
B b;
return 0;
}
This gives the following output:
A ctor
C ctor
A ctor
B ctor
B dtor
A dtor
I don't understand why this is happening. For example, I know that a new C object is being created, that's derived from A, so the A ctor runs first. Then the C ctor runs. And then I thought the C dtor runs, but for some reason the A ctor is running again.
C is created, this constructs A (base class) and then C
B is created, this constructs A (base class) and then B
B is destroyed (goes out of scope), this destructs B and then A (base class)
C is never deleted, so it's leaked and the destructors are never called.
I have a function that gets an object of 'A', it's called: func. I send it an object of B.
Shouldn't it activate the constructor of B? cause I send an object of B although I have to send an object of A. I really don't know why this function prints:
A()
DESTRUCTOR A
and not:
CONSTRUCTOR A
CONSTRUCTOR B
B()
DESTRUCTOR B
DESTRUCTOR A
doesn't it have to multiply the object B because the func gets A a and not A& a?
this is my code:
class A
{
public:
A() { cout << "CONSTRUCTOR A\n"; }
~A() { cout << "DESTRUCTOR A\n"; }
virtual void f() { cout << "A()" << endl; }
};
class B: public A
{
public:
B() { cout << "CONSTRUCTOR B\n"; }
~B() { cout << "DESTRUCTOR B\n"; }
virtual void f() { cout << "B()" << endl; }
};
void func(A a) {
a.f();
}
int main() {
B b;
func(b);
return 0;
}
Because if you send son but the function asks for the father class it treats the child as a father.
class A
{
public:
A() { cout << "CONSTRUCTOR A\n"; }
~A() { cout << "DESTRUCTOR A\n"; }
virtual void f() { cout << "A()" << endl; }
};
class B: public A
{
public:
B() { cout << "CONSTRUCTOR B\n"; }
~B() { cout << "DESTRUCTOR B\n"; }
virtual void f() { cout << "B()" << endl; }
};
void func(B a) {
a.f();
}
int main() {
B b;
func(b);
return 0;
}
if you try this code you see the result you expect.
I think the reason that you are confused is because you are passing by value instead of a pointer. That is why the B object is being treated as an A, since func takes a value of A it treats the object as A by default, which also means that the wrong destructor is being called.Run this code and you will understand better.
#include <iostream>
using namespace std;
class A
{
public:
A() { cout << "CONSTRUCTOR A\n"; }
~A() { cout << "DESTRUCTOR A\n"; }
virtual void f() { cout << "A()" << endl; }
};
class B: public A
{
public:
B() { cout << "CONSTRUCTOR B\n"; }
~B() { cout << "DESTRUCTOR B\n"; }
virtual void f() { cout << "B()" << endl; }
};
void func(A * a) {
a->f();
}
int main() {
B * b = new B();;
cout << "\n";
func(b);
cout << "\n";
delete b;
return 0;
}
This is basically the point of virtual functions, when using inheritance you want to able able to pass everything in as a parent class pointer. However the method you want called is the child classes method. When you pass by value the object has to be treated as what it is passed in as.
I was doing a little experiment with virtual destructors to review - wondering if anyone has a simple explanation for the following (using vs 2010):
I Define class hierarchy A-B-C-D, D inherits C, C inherits B, B inherits A, A is the Base;
ran 2 experiments:
First experiment -
A has a virtual Destructor.
B has a non-Virtual Destructor
C has a virtual Destructor
D has a non virtual Destructor
//----------------------------
Allocate 4 objects on the heap of type D - Point a pointer of A*, B* and C* at the first 3 - Leave the 4th as a D* for Completeness.
Delete all 4 Pointers.
As I expected, in all 4 instances, the complete destructor chain is executed in reverse order from D down to A, freeing all memory.
Second Experiment -
A has a non-virtual Destructor ** Changed A to non virtual
B has a non-Virtual Destructor
C has a virtual Destructor
D has a non virtual Distructor
Allocate 4 objects on the heap of type D - Point a pointer of A*, B*, and C* at the first 3 - Leave the 4th as a D* for Completeness.
Deleting C* and D* pointers:
the complete destructor chain is executed in reverse order from D down to A, freeing all memory.
Deleting B*:
B and then A Destructor is run (leak)
Deleting A*:
Only A Destructor is run (leak)
Can anyone explain Why this is?
When D type opjects are allocated in experiment 2, its immediate base class (C) has a virtual destructor - doesnt that tell the compiler to track it with a Vptr and know the memory type? REGARDLESS of the reference?
Thanks
Mike
When D type opjects are allocated in experiment 2, its immediate base class (C) has a virtual destructor - doesnt that tell the compiler to track it with a Vptr and know the memory type? REGARDLESS of the reference?
No.
In your second test case, A and B don't have vptrs/vtables. (And even if they did, a non-virtual member function would still be resolved statically, not dynamically.)
Put another way, a base class does not "inherit" information (such as whether functions are virtual) from derived classes.
When you delete an A* without a virtual destructor, at compile-time the compiler does not know that it will point at runtime to an object with a virtual destructor. The deletion might be of an object with a virtual destructor -- or not. Dynamic binding does not occur.
Is your actual question about why one would use virtual vs non-virtual destructors? Cos having a base class with a non-virtual destructor is bad. See the faq
I have composed almost identical question, so I thought to share it.
Note that I also added some usage of virtual function within the different Ctor's in order to illustrate how it is work (shortly, in each Ctor, the V-table is updated only "up to it" , meaning the virtual function implementation that will be invoked is the most derived until "this point" of the inheritance chain).
A note of mine: In the sample code that runs the given classes, I also added a creation of "Derived" object (B and D) on the STACK --> in order to emphasis that all the considerations regarding "virtual-ness" of Dtor's are applicable when we use pointers (of whatever type) to the class instance.
class A;
void callBack(A const& a);
class A
{
public:
A() { std::cout << "A Ctor " << std::endl; f1(); callBack(*this); /* f3();*/ }
~A() { std::cout << "A Dtor " << std::endl; }
void f1() { std::cout << "A : f1 " << std::endl; }
virtual void f2() const { std::cout << "A : f2 " << std::endl; }
virtual void f3() = 0;
};
class B : public A
{
public:
B() { std::cout << "B Ctor " << std::endl; f1(); callBack(*this); f3(); }
~B() { std::cout << "B Dtor " << std::endl; }
void f1 () { std::cout << "B : f1 " << std::endl;}
void f2() const { std::cout << "B : f2 " << std::endl; }
virtual void f3() { std::cout << "B : f3 " << std::endl; }
};
class C : public A
{
public:
C() { std::cout << "C Ctor " << std::endl; f1(); callBack(*this); f3(); }
virtual ~C() { std::cout << "C Dtor " << std::endl; }
void f1() { std::cout << "C : f1" << std::endl;}
void f2() const { std::cout << "C : f2" << std::endl; }
virtual void f3() const { std::cout << "C : f3" << std::endl; }
};
class D : public C
{
public:
D() { std::cout << "D Ctor " << std::endl; f1(); callBack(*this); }
~D() { std::cout << "D Dtor " << std::endl; }
void f1() { std::cout << "D : f1" << std::endl; }
void f2() const { std::cout << "D : f2 " << std::endl; }
virtual void f3() { std::cout << "D : f3 " << std::endl; }
};
void callBack(A const& a) { a.f2(); }
// =================================================================================================================================
int main()
{
std::cout << "Start of main program" << std::endl;
std::cout << "Creating a D object on the heap" << std::endl;
D* pd = new D;
C* pc = new D;
A* pa = new D;
if (true)
{
std::cout << "Entering Dummy scope # 1 and creating B object on the stack" << std::endl;
B b;
std::cout << "Leaving Dummy scope # 1 with B object within it" << std::endl;
}
if (true)
{
std::cout << "Entering Dummy scope # 2 and creating D object on the stack" << std::endl;
D d;
std::cout << "Leaving Dummy scope # 2 with D object within it" << std::endl;
}
std::cout << "Calling delete on pd (D*) which points on a D object" << std::endl;
delete pd;
std::cout << "Calling delete on pc (C*) which points on a D object" << std::endl;
delete pc;
std::cout << "Calling delete on pa (A*) which points on a D object" << std::endl;
delete pa;
std::cout << "End of main program" << std::endl;
return 0;
}