Antoine C.
Antoine C.

Reputation: 3962

Override function and its calls in base class

Let's say I've got these two classes:

class A {
public:
    A() { foo() };
protected:
    virtual void foo();
};

class B : public A {
public:
    B() : super();
private:
    typedef A super;
    void foo();
};

If I create an object B, is there a way to force A's constructor to use the overriden method when it is called ?

Upvotes: 0

Views: 108

Answers (4)

Vimal
Vimal

Reputation: 456

Calls to Virtual functions are resolved using a virtual table. Any class having at least one virtual function ( and all its derived classes ) will have a virtual table each ( in this case both A and B ) and this virtual table will contain address of all the virtual functions in the order in which they have been declared. When an object of any such class is created, the object contains a hidden pointer, vptr, that points to the virtual table. So a virtual function call is resolved by first going to the virtual table using vptr, then adding the offset of the called function to get the address of the function and then calling the function using this address. Now important thing is that the vptr is initialized in the constructor of a class and in a particular constructor it will point to the virtual table of that particular class. In this case when object of B is created, the vptr in the constructor of A ( base class constructor is called first ) will point to the virtual table of A and when the constructor of B gets called the vptr will only then point to the virtual table of B. That means in the constructor of A, vptr is pointing to A's virtual table. So when you call foo(), the compiler will go to A's virtual table, fetch the address of foo() which in this case is A's foo() and call this function. This is why we usually say that virtual mechanism does not work inside constructor. The reason is that the vptr is not fully initialized and is not pointing to the most derived class's vtable. I hope this helps.

Upvotes: 0

quantdev
quantdev

Reputation: 23813

C++ Standard, section § 12.7 [Construction and Destruction] :

Member functions, including virtual functions (10.3), can be called during construction or destruction (12.6.2).When a virtual function is called directly or indirectly from a constructor or from a destructor, including during the construction or destruction of the class’s non-static data members, and the object to which the call applies is the object (call it x) under construction or destruction, the function called is the final overrider in the constructor’s or destructor’s class and not one overriding it in a more-derived class

When you are in A constructor, your object is an A at this point, it doesn't matter if the call was made from B constructor.

So A::foo will always be called.

Upvotes: 1

Jarod42
Jarod42

Reputation: 218323

When A constructor is called from B, B is not yet construct, so A::foo is not called virtually.

you may create a function to create and initialize your object:

struct Base
{
    virtual ~Base();
    virtual void init();
};

struct D : Base
{
    void init() override;
};

D make_D()
{
    D d;
    d.init();
    return d;
}

Upvotes: 0

Joy Hyuk Lee
Joy Hyuk Lee

Reputation: 776

No. It isn't. According to Effective c++, when object is initializing, The virtual functions is not working. (I wrote by mobile phone so here can be typos)

Best regards.

Upvotes: 2

Related Questions