Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I overload pure virtual method in the base class?

In the example below I have a abstract class with pure virtual method (aka FUN1) and a normal method (aka FUN2).

#include <iostream>

class A
{
public:
        virtual void fun(int i) = 0; // FUN1
        void fun() { this->fun(123); } // FUN2
};

class B : public A
{
public:
        virtual void fun(int i) { std::cerr << i << std::endl; }
};

int main(int,char**)
{
        B b;
        b.fun();
}

Why can't I call FUN2 on derived class? g++ gives an error:

main.cpp:19:8: error: no matching function for call to ‘B::fun()’


EDIT: note that Overload of pure virtual function question is different. I don't want to override methods.

like image 473
user2449761 Avatar asked Apr 12 '15 21:04

user2449761


2 Answers

This is how derived class member lookup works: in the expression b.fun(), fun is first looked up in the scope of class B, and the lookup finds B::fun(int). So it stops and never finds A::fun().

Relevant section of the standard is 10.2 [class.member.lookup]/4:

If C contains a declaration of the name f, the declaration set contains every declaration of f declared in C that satisfies the requirements of the language construct in which the lookup occurs. (...) If the resulting declaration set is not empty, the subobject set contains C itself, and calculation is complete.

To make the base class function directly accessible you can use a using declaration in the derived class, i.e. using A::fun;.

For methods that are implemented in the base class an alternative is sometimes to qualify to call, i.e. b.A::fun().

like image 76
Anton Savin Avatar answered Sep 18 '22 18:09

Anton Savin


Try to add using A::fun; statement in B class :

#include <iostream>

class A
{
public:
    virtual void fun(int i) = 0; // FUN1
    void fun() { this->fun(123); } // FUN2
};

class B : public A
{
public:
    using A::fun;
    virtual void fun(int i) { std::cerr << i << std::endl; }
};

int main(int, char**)
{
    B b;
    b.fun();
    b.fun(5);
}
like image 24
AdamF Avatar answered Sep 19 '22 18:09

AdamF