In the example below I have a abstract class with pure virtual method (aka FUN1) and a normal method (aka FUN2).
#include
class A
{
public:
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);
}
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 namef
, the declaration set contains every declaration off
declared inC
that satisfies the requirements of the language construct in which the lookup occurs. (...) If the resulting declaration set is not empty, the subobject set containsC
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()
.