Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If an overridden C++ function calls the parent function, which calls another virtual function, what is called?

I'm learning about polymorphism, and I am confused by this situation: Let's say I have the following C++ classes:

class A{
    ...
    virtual void Foo(){
        Boo();
    }
    virtual void Boo(){...}
}

class B : public A{
    ...
    void Foo(){
        A::Foo();
    }  
    void Boo(){...}
}

I create an instance of B and call its Foo() function. When that function calls A::Foo(), will the Boo() method used be that of class A or B? Thanks!

like image 917
ODdol Avatar asked Jun 29 '10 13:06

ODdol


3 Answers

Unless you qualify a function call with the class, all method calls will be treated equal, that is dynamic dispatch if virtual, static dispatch if not virtual. When you fully qualify with the class name the method you are calling you are effectively disabling the dynamic dispatch mechanism and introducing a direct method call.

class A{
    virtual void Foo(){
        Boo();           // will call the final overrider
        A::Boo();        // will call A::Boo, regardless of the dynamic type
    }
    virtual void Boo();
};
class B : public A{
    void Foo(){
        //Foo();         // Would call the final overrider 
                         // (in this case B: infinite recursion)
        A::Foo();        // Will call A::Foo, even if the object is B
    }  
    void Boo();
};

The implicit this pointer is not an important part of the discussion here, as exactly the same happens when the call is made with an explicit object:

B b;
b.Foo();    // will call B::Foo -- note 1
b.A::Foo(); // will call A::Foo

Note 1: in this example, the compiler can elide the dynamic dispatch mechanism as it knows the concrete type of the instance (it sees the definition and it is not a reference/pointer) but you can imagine the same would happen if b was a reference, or equivalently if it was a pointer with -> instead of .

like image 50
David Rodríguez - dribeas Avatar answered Nov 15 '22 02:11

David Rodríguez - dribeas


Since Boo() is virtual, the derived class' override is called.

Boo(); is just a short-hand for this->Boo();, where you can see that a virtual function is called through a pointer. (this is of type A* const within Foo().) And virtual functions called through a reference or a pointer will always call the override in the most-derived class (except when called from a constructor or destructor).

like image 27
sbi Avatar answered Nov 15 '22 02:11

sbi


Inside A,

virtual void Foo(){
        Boo();
    }

gets translated to this->Boo() ;since Boo is declared virtual in A, the derived class's method Boo gets called. Try not declaring Boo as virtual in A just for experimentation -- you'd see that A->Boo() is getting called.

Arpan

like image 35
Fanatic23 Avatar answered Nov 15 '22 04:11

Fanatic23