user1745995
user1745995

Reputation: 151

Call to non virtual function in derived class from base class (C++)

test is not a virtual function and is defined in both base and derived class. I have a derived class object. It ends up calling test of the base class instead of the one in the derived class. Why is this happening? How can I set it up such that test is called depending on the object type.

current o/p

B func                                                                                                         
A f1                                                                                                           
A test

I want it to be

B func                                                                                                         
A f1                                                                                                           
B test
#include <iostream>

using namespace std;
class A {
    protected:
    void test()
    {
        cout<<"A test"<<endl;
    }
    void f1(){
        cout<<"A f1" <<endl;
        test();
    }
};
class B: public A {
    protected: 
    void test()
    {
        cout<<"B test" <<endl;
    }
   public:
    void func(){
        cout<<"B func" << endl;
        f1();

    }

};
int main()
{
    B tmp;
    tmp.func();
    return 0;
}

Upvotes: 1

Views: 1483

Answers (1)

Coral Kashri
Coral Kashri

Reputation: 3506

There ere 2 ways to archive the desired result:

Using virtual
Declaring base class functions as a virtual will make sure to call the most higher inheritance of the target functions by default. For example, in your case:

class A {
protected:

    /**
     * Declared also in the derived class, so as long the current object is the derived class,
     * this function will be called from the derived class.
     * [Enabled only due to the use of the `virtual` keyword].
     */
    virtual void test() {
        cout << "A test" << endl;
    }

    void f1() {
        cout << "A f1" << endl;
        test();
    }
};

Using CRTP [Huge overhead to archive something you can archive using virtual]

template <class Derived> // Template param that will accept the derived class that inherit from this class.
class A {
protected:
    virtual void test() const {
        cout << "A test" << endl;
    }

    void f1() const {
        cout << "A f1" << endl;
        static_cast<Derived const&>(*this).test(); // Call test() function from the derived class.
    }
};

class B: public A<B> { // inherit A that accepts template argument this derived class
// protected:
public: // Pay attention that now test should be public in the derived class in order to access it via the base class.
    void test() const override {
        cout << "B test" << endl;
    }

//public:
    void func() const {
        cout << "B func" << endl;
        f1();
    }
};

Read more about CRTP.

Upvotes: 2

Related Questions