我的C++
代码如下:
#include<iostream>
using namespace std;
class A
{
public:
virtual void f(int i)
{
cout << "A's f(int)!" << endl;
}
void f(int i, int j)
{
cout << "A's f(int, int)!" << endl;
}
};
class B : public A
{
public:
virtual void f(int i)
{
cout << "B's f(int)!" << endl;
}
};
int main()
{
B b;
b.f(1,2);
return 0;
}
在编译期间我得到:
g++ -std=c++11 file.cpp
file.cpp: In function ‘int main()’:
file.cpp:29:9: error: no matching function for call to ‘B::f(int, int)’
file.cpp:29:9: note: candidate is:
file.cpp:20:16: note: virtual void B::f(int)
file.cpp:20:16: note: candidate expects 1 argument, 2 provided
当我尝试在B的f(int)之后使用覆盖时,我得到了同样的错误。
C ++中是否可以只覆盖1个方法?我一直在寻找使用override
的代码示例,它将在我的机器上编译但尚未找到。
答案 0 :(得分:10)
问题是,班级f()
中的虚拟函数B
隐藏了 A
的非虚拟重载,名称相同。您可以使用using
声明将其纳入范围:
class B : public A
{
public:
using A::f;
// ^^^^^^^^^^^
virtual void f(int i)
{
cout << "B's f(int)!" << endl;
}
};
答案 1 :(得分:5)
您将名称“f”覆盖为方法名称。因此任何重载都将被覆盖。
您可以使用using
关键字,只是告诉编译器查看基类:
class B : public A
{
public:
using A::f;
virtual void f(int i)
{
cout << "B's f(int)!" << endl;
}
};
答案 2 :(得分:4)
你被C ++中的名称查找工作所困扰。编译器搜索连续的范围,直到找到至少一个具有匹配名称的项目的范围。
假设item是一个函数,它会在具有该范围的名称的函数中进行重载解析。如果这些都不起作用,它不继续搜索更多范围以找到更合适的。
然而,在这种情况下,你可以让它来搜索父类:
class B : public A
{
public:
using A::f;
virtual void f(int i)
{
cout << "B's f(int)!" << endl;
}
};
乍一看,似乎using
语句可能会产生歧义。例如,使用using A::f;
,f(int)
的范围(B
和A::f(int)
中可以看到两个 B::f(int)
个函数。 C ++也有一些规则来涵盖这一点,所以如果你在b.f(3);
中添加(例如)main
(using A::f;
到位)你仍然不会有歧义 - 它如你所料,打电话给b::f(int)
。
答案 3 :(得分:1)
派生类中定义的函数f
通过名称f
隐藏基类函数。
要将隐藏函数放在派生类的范围内,您需要添加:
using A::f;
到您的基类定义。
好读:
<强> What's the meaning of, Warning: Derived::f(char) hides Base::f(double)? 强>
答案 4 :(得分:0)
是的,可以只覆盖一个类的一个方法,使其成为虚拟方法。在继承的类中声明时,非虚拟将被遮蔽。