Search code examples
c++c++11overridingderived-class

Is there another way to prevent a derived method from superclass being called instead of the base class one, like with a keyword or something?


As I am practicing C++ with some of my colleagues, one of them "experienced a bug" within a derived class. Long story short, he was calling the base method (callFoo) and he was expecting to be calling A::Foo(), but he got B::Foo() instead.

Here's a complete example of what I am actually asking. I don't really know how to explain better than this. I have indeed found a solution, but that solution is awkward; it makes the code kind of hard to "sanitize" for the future extensions of our classes. Are there other solutions available? (Maybe a keyword?)

n.b. The example is purely demonstrative: in the original example callFoo() was the operator= for Class A. I tried my best to simplify it.

Example 1: Unwanted behavior

#include <iostream>

class A{
    public:
        virtual void Foo(){
            std::cout<<"A Foo\n";
        }

        virtual void callFoo(){
            Foo();
        }
};

class B: public A{
    public:
        virtual void Foo() override{
            std::cout<<"B Foo\n";
        }
};


int main(){
    B mB;

    mB.Foo();
    mB.callFoo();

    return 0;
}

Example 2: The non-ideal fix; are there other solutions?

class A{
    public:
        virtual void Foo(){
            std::cout<<"A Foo\n";
        }

        virtual void callFoo(){
            A::Foo();
        }
};

Solution

  • It is clear that you are creating an object of Derived class and trying to invoke callFoo() function present in the base Class. I will try to visualize this step by step :

    1. B mB ---> Since we are creating an object of Derived class , the VPtr will point the to the Vtable of Derived Class.
    2. mB.callFoo(); ---> the Vptr is still pointing to the VTable of the Derived class.Since object is trying to invoke callFoo() , it doesn't found the entry in the VTable of Derived Class .It invokes the callFoo() of Base Class. Now Here is the main catch ,the Foo() is called from the body of callFoo() but again as mentioned earlier it will Search the entry of this function in VTable of the Derived Class and hence it will invoke the Derived class Foo().

    Hence we need to explicitly say to compiler that , we need base version of the method and use A::Foo() to call Base class method.

    For further details on VTable and VPtr , there is a useful link in stack-overflow: VPtr And VTable In Depth C++