Reputation:
#include <iostream>
using namespace std;
class A {
public:
void m1(){ cout << 'A'; }
virtual void m2(){ cout << 'B'; }
virtual void m3(){ cout << 'C'; }
};
class B: public A {
public:
void m1(){ cout << 'D'; }
void m2(){ cout << 'E'; }
};
class C: public B {
public:
void m3(){ cout << 'F'; }
};
int main()
{
cout << "Hello World!" << endl;
A* a = new B();
a->m1();
a->m2();
a->m3();
return 0;
}
What will be the output? I initially thought that it will be "D E C" but after running the program it was "A E C"
Could one elaborate what is going on behind this line of code:
A* a = new B();
Upvotes: 1
Views: 114
Reputation: 171127
Virtual member functions are dispatched based on the dynamic (run-time) type of the object. Non-virtual member functions are dispatched based on the static (compile-time) type of the object.
A *a = new B();
a
points to an object whose dynamic type is B
. The static type of a
is A*
, however, which means that the static type of *a
is A
.
Virtual functions (m2
and m3
) are dispatched based on the dynamic type, so B::m2
and B::m3
are called.
Non-virtual functions are dispatched based on the static type. The static type of *a
is A
, so A::m1
is called.
What exactly is going on in the new
line? A new object of type B
is created dynamically, and the new
expression returns a pointer to that object (of type B*
). Then, a derived-to-base conversion is applied to that pointer to convert it to an A*
, which is used to initialise the variable a
.
In pseudo-code, showing intermediary steps:
B *tmp_b = new B(); // allocate and initialise B object
A *tmp_a = convert_derived_to_base(tmp_b);
A *a = tmp_a;
Upvotes: 5
Reputation: 1122
void m1(){ cout << 'A'; }
virtual void m2(){ cout << 'B'; }
virtual void m3(){ cout << 'C'; }
The output is totally fine as per your programs code.
void m1(){ cout << 'A';
is not a virtual function.
So a->m1();
calls the base version of m1
and gives the o/p as A
.
m2()
is a virtual function and it has a new implementation inside class B.
void m2(){ cout << 'E'; }
So a->m2();
calls the class B
version of the m2
function and gives the output E
.
There is no new implementation of m3
inside class B
.
So a->m3();
calls m3
which is inherited from class A
.
To get the o/p as DEC
you have to just change the m1
function to a virtual function like below
class A {
public:
virtual void m1(){ cout << 'A'; }
virtual void m2(){ cout << 'B'; }
virtual void m3(){ cout << 'C'; }
};
Upvotes: 0
Reputation: 117876
The output will be
AEC
The reason is that A::m1
was not declared virtual
. In this line
A* a = new B();
You are declaring an A*
variable named a
, which is actually an instance of the derived class B
. This is allowed because "B
is a type of A
".
When a function is declared virtual
, if a derived class defines that function then the one in the base class is overridden with the version in the derived class. So the following calls will be made
a->m1(); // A::m1
a->m2(); // B::m2
a->m3(); // A::m3
Upvotes: 0
Reputation: 1598
Here Class A
is your parent class, so to override parent class's method you need to make it virtual
in class A. So that Class B
's method will be called. Please see more information on Virtual Functions
Upvotes: 0
Reputation: 351
m1 method is not virtual in class A, it can not be override .m2 is virtual so it override with class B method .
Upvotes: 1