8

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.

Community
  • 1
  • 1
user2449761
  • 1,169
  • 13
  • 25
  • possible duplicate of [Overload of pure virtual function](http://stackoverflow.com/questions/15827632/overload-of-pure-virtual-function) – Axalo Apr 12 '15 at 21:52

2 Answers2

10

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().

Anton Savin
  • 40,838
  • 8
  • 54
  • 90
7

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);
}
AdamF
  • 2,501
  • 17
  • 30