Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ : What is happening when a non-overridden calls a overridden method?

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) {}
}
like image 644
codecitrus Avatar asked Oct 25 '15 19:10

codecitrus


2 Answers

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()
like image 55
el.pescado - нет войне Avatar answered Nov 29 '22 10:11

el.pescado - нет войне


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();
}
like image 22
kubanrob Avatar answered Nov 29 '22 11:11

kubanrob