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.
Related
In the following code, will small c will leak ?
I believe that not, as it is not dynamically allocated, the struct will be deleted entirely
From my peers I got the following answers :
It is undefined behavior
It will leak
It wont leak
Here is the code :
class A
{
public:
void printA() { cout << "A" << endl;}
virtual void printB() { cout << "B" << endl;}
int a;
};
class C : public A
{
public :
void printA() { cout << "C" << endl;}
void printB() { cout << "D" << endl;}
int c;
};
int main()
{
A* bla = new C();
bla->printA();
bla->printB();
delete bla;
return 0;
}
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 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.
hey there, why is the base destructor called twice at the end of this program?
#include <iostream>
using namespace std;
class B{
public:
B(){
cout << "BC" << endl; x = 0;
}
virtual ~B(){
cout << "BD" << endl;
}
void f(){
cout << "BF" << endl;
}
virtual void g(){
cout << "BG" << endl;
}
private:
int x;
};
class D: public B{
public:
D(){
cout << "dc" << endl; y = 0;
}
virtual ~D(){
cout << "dd" << endl;
}
void f(){
cout << "df" << endl;
}
virtual void g(){
cout << "dg" << endl;
}
private:
int y;
};
int main(){
B b, * bp = &b;
D d, * dp = &d;
bp->f();
bp->g();
bp = dp;
bp->f();
bp->g();
}
Destructors are called in order, as if they were unwinding the effects of the corresponding constructors. So, first the destructors of the derived objects, then the destructors of the base objects. And making the destructors virtual doesn't have any impact on calling / not calling the base class destructor.
Also to mention, your example could be simplified this way (this code also results in calling the base destructor twice and the derived destructor once):
struct A {
~A() {
// ...
}
};
struct B: A {
~B() {
// ...
}
};
int main() {
A a;
B b;
}
Once it is called for b and once for d
Note when destructor of D called it is automatically calls the destructor of B it is different from ordinary virtual functions. where you need explicitly call base class function to use it.