0

In the following code:

#include <iostream>
using namespace std;

class A {
    public:
    A() {
        cout << " A constructor \n";
        sum(2,4);
    }
    virtual int sum(int a, int b){
        cout << "Base sum \n";
        return a + b;
    }
};

class B : public A {
    public:
    B() : A() {
        cout << " B constructor \n";
    }

    int sum(int a, int b){
        cout << "Overloaded sum \n";
        return (a + b) * 10;
    }
};

int main(){
    A* a = new B();
    // a->sum(4,5);
}

Why is A's sum invoked even though I have marked it as virtual and overloaded it in B ? At runtime, with the help of vtable shouldn't B::sum() be invoked ?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
brainydexter
  • 19,826
  • 28
  • 77
  • 115

2 Answers2

5

Because by the time you call the method, a isn't an object of type B yet.

Avoid calling virtual methods from constructors: it will lead to unexpected results (unless of course you expect this exact behavior, in which case you'd be spot on).

At runtime, with the help of vtable shouldn't B::sum() be invoked ?

Not really, because the object doesn't have the vtable of B at that point.

amalloy
  • 89,153
  • 8
  • 140
  • 205
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • 2
    And for completeness, something similar applies to making such calls from destructors. – juanchopanza Aug 09 '12 at 05:58
  • 1
    I'm curios to learn. What are the disadvantages (unexpected results) of calling virtual methods from constructors ? (other than calling virtual functions and expecting the derived function would be called instead) – brainydexter Aug 09 '12 at 05:59
  • @juanchopanza can you please elaborate on that ? – brainydexter Aug 09 '12 at 06:00
  • 2
    @brainydexter see this [Scott Meyers link](http://www.artima.com/cppsource/nevercall.html). Basically, by the time you get to the base class destructor the derived object doesn't really exist anymore. – juanchopanza Aug 09 '12 at 06:03
  • aha yes! since derived objects are destroyed first and then the base object, thus there is no derived object there at the time. – brainydexter Aug 09 '12 at 06:05
0

The base constructor is executed first when you instantiate a derived class. That means that while the base constructor is executing, the construction of the derived object is not finished yet.

Avoid these scenarios by limiting the action in the constructor to what it is intended: initialising the object.

brainydexter
  • 19,826
  • 28
  • 77
  • 115
steffen
  • 8,572
  • 11
  • 52
  • 90