user4833046
user4833046

Reputation:

explanation on simple c++ inheritance

#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

Answers (5)

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

Rndp13
Rndp13

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

Cory Kramer
Cory Kramer

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

Amol Saindane
Amol Saindane

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

Venkata Naidu M
Venkata Naidu M

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

Related Questions