在下面的例子中,我有一个带有纯虚方法(又名FUN1)的抽象类和一个普通方法(又名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();
}
为什么我不能在派生类上调用FUN2? g ++给出错误:
main.cpp:19:8:错误:没有匹配函数来调用'B :: fun()'
编辑:请注意Overload of pure virtual function问题不同。我不想覆盖方法。
答案 0 :(得分:7)
这是派生类成员查找的工作原理:在表达式b.fun()
中,首先在fun
的范围内查找class B
,查找找到B::fun(int)
。所以它停止了,永远不会找到A::fun()
。
标准的相关部分是10.2 [class.member.lookup] / 4:
如果
C
包含名称f
的声明,则声明集包含声明的f
声明C
满足查找发生的语言构造的要求。 (...)如果生成的声明集不为空,则子对象集本身包含C
,并且计算完成。
要使基类功能可直接访问,您可以在派生类中使用using
声明,即using A::fun;
。
对于在基类中实现的方法,有时候替代方案有资格进行调用,即b.A::fun()
。
答案 1 :(得分:5)
尝试在B类中添加using A::fun;
语句:
#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);
}