5

The version of a overridden method that gets invoked depends on if you care calling the function "through" the base class or "through" the derived class. However, I am finding if I call a non-overridden method, and the overridden method calls some function that is overridden, then the base class version is still called, even though I am accessing the instance through pointer to the derived class. Could someone explain why this happens?

CODE:

class Base {
public:
    void display() {
        foo();
    }
    void foo() {
        cout << "Base.foo()" << endl;
    }
};

class Derived : public Base {
public:
    void foo() {
        cout << "Derived.foo()" << endl;
    }
};

int main() {
    Derived* derived = new Derived();
    derived->display();
    while (true) {}
}
codecitrus
  • 659
  • 6
  • 17

4 Answers4

6

the base class version is still called, even though I am accessing the instance through pointer to the derived class. Could someone explain why this happens?

Although you call method via pointer to derived class, your method is not virtual, so static dispatch is used, so Base::display() calls Base::foo() directly, even if it is overridden in subclasses. To achieve behavior you want, you must use dynamic dispatch, i.e. mark your methods as virtual.

class Base {
public:
    void display() {
        foo();
        bar();
    }
    void foo() {
        cout << "Base.foo()" << endl;
    }
    virtual void bar() {
        cout << "Base.bar()" << endl;
    }
};

class Derived : public Base {
public:
    void foo() {
        cout << "Derived.foo()" << endl;
    }
    virtual void bar() {
        cout << "Derived.bar()" << endl;
    }
};

int main() {
    Derived* derived = new Derived();
    derived->display();
}

Output:

Base.foo()
Derived.bar()
1

The thing is: you do not have overridden any function; you have hidden its name.

In C++, only virtual functions (see C++ FAQ) can be overridden. Making the Base::foo() virtual yields the expected result: (run code!)

class Base {
public:
    void display() {
        foo();
    }
    virtual void foo() {
        cout << "Base.foo()" << endl;
    }
};

class Derived : public Base {
public:
    void foo() {
        cout << "Derived.foo()" << endl;
    }
};

int main() {
    Derived* derived = new Derived();
    derived->display();
}
Community
  • 1
  • 1
kubanrob
  • 160
  • 2
  • 8
0
virtual qualifier needs to be used for methods that need to be overridden.
ex:
 class Base {
public:
    void display() {
        foo();
    }
    virtual void foo() {
        cout << "Base.foo()" << endl;
    }
};

class Derived : public Base {
public:
    virtual void foo() {
        cout << "Derived.foo()" << endl;
    }
};

int main() {
    Derived* derived = new Derived();
    derived->display();
    while (true) {}
}
Nandu
  • 808
  • 7
  • 10
0

You are not using a virtual function.

An object in a class hierarchy has two types: It's "real" class, and the class that the compiler thinks at the moment that it has.

When you call a virtual function, the compiler always calls the function that belongs to the "real" class. When you call a non-virtual function, the compiler calls the function belong to the class that it thinks is the objects class.

While executing code in a subclass, the compiler thinks that *this is an object of the subclass. Therefore calling a non-virtual function will call the function belonging to that subclass.

gnasher729
  • 51,477
  • 5
  • 75
  • 98