Home > Enterprise >  Overriding non-virtual function from abstract grandparent class
Overriding non-virtual function from abstract grandparent class

Time:11-13

I am learning and playing around with inheritance and abstract classes. I've run into a predicament that I would appreciate some clarifications on.

I am trying to override a non-virtual function from an abstract grandparent class. I am getting an error saying that 'member function declared with 'override' does not override a base class member.

I can call the original non-virtual function from child class instances in main(), but not override them in child classes?

Here's the code.

UPDATE: Error went away when I marked the function as virtual, I would still appreciate an explanation as to why that virtual is necessary?

#include <iostream>

using namespace std;


class A
{
public:
    virtual string GetClassName() = 0;
    void foo(); // <--- this is the problem function
    {
        cout << "foo" << endl;
    }
};


class B : public A
{
public:
    string GetClassName() override
    {
        return "B";
    }
};


class C1 : public B
{
public:
    string GetClassName() override
    {
        return "C";
    }
};


class C2 : public B
{
public:
    void foo() override // ERROR:member function declared with override does not override a base class member.
    {
        cout << "foo c1" << endl;
    }
};


// testing interface
void printName(A* ptr)
{
    cout << ptr->GetClassName() << endl;
}


int main()
{

    B* b = new B();
    C1* c1 = new C1();
    C2* c2 = new C2();

    printName(b); // prints B
    printName(c1); // prints C
    printName(c2); // prints B

    b->foo(); // prints foo, inherited directly from abstract class
    c1->foo(); // prints foo, inherited directly from abstract class
    c2->foo(); // ??
}

CodePudding user response:

You cannot override a non-virtual function. It is as simple as that.

Methods in child classes can hide methods of parent classes when they have the same name, for example:

struct A {
    void foo(){}
};
struct B : A {
    void foo() {}
};

But thats not overriding. To override the method must be virtual. Thats one of the conditions that the override specifier helps to check:

struct A {
    virtual void foo(){}
};
struct B : A {
    void foo() override {}  // <- error if A::foo is not virtual
};

PS: I have seen poor tutorials, that use the first example and call that overriding. Thats just wrong.

  •  Tags:  
  • c
  • Related