C++ 派生类再次重写基类函数

C++ 派生类再次重写基类函数,c++,C++,在thread中,接受答案的作者解释了为什么编译器无法解析派生类中被重写的方法。但是,该示例与类型转换解析有关,即基重载方法和派生重载方法都只有一个参数,并且歧义仅限于该参数类型 但是,当重载方法具有不同数量的参数时,模糊性在哪里呢,如本例中所示 请注意,我不是问为什么示例会产生编译错误,而是问为什么语言是这样设计的。 #include <iostream> using namespace std; class A { public: inline int f(int x)

在thread中,接受答案的作者解释了为什么编译器无法解析派生类中被重写的方法。但是,该示例与类型转换解析有关,即基重载方法和派生重载方法都只有一个参数,并且歧义仅限于该参数类型

但是,当重载方法具有不同数量的参数时,模糊性在哪里呢,如本例中所示

请注意,我不是问为什么示例会产生编译错误,而是问为什么语言是这样设计的。

#include <iostream>
using namespace std;

class A
{
public:
   inline int f(int x) { return x; }
};

class B: public A
{
public:
   inline int f(int x, int y) { return x+y; }
};


int main()
{
  B b;

  cout << b.f(1) << endl; // COMPILE ERROR
  cout << b.f(1,2) << endl;
}
#包括
使用名称空间std;
甲级
{
公众:
内联int f(int x){return x;}
};
B类:公共A
{
公众:
内联int f(int x,int y){返回x+y;}
};
int main()
{
B B;

cout编译器将在类
B
中查找函数
f
的实现。编译器找到了这样一个实现,它有两个参数。您只提供了一个参数,因此存在错误。

编译器出现错误的原因是
f
来自类
a
f>隐藏
在类
B

当编译器执行成员名称查找时,它仅在对象的类中找不到名称时才使用基类,因此基类中是否有成员具有适当的调用参数列表并不重要

根据标准:

10.2.5否则(即,C不包含f的声明或生成的声明集为空),S(f,C)为 最初为空。如果C有基类,则计算每个直接基类子对象Bi中f的查找集 , 并将每个这样的查找集S(f,Bi)依次合并为S(f,C)


在C++中,名称查找将在找到一个基类中的请求名称后停止寻找其他名称。 在您的例子中,名称

f
B
中定义,因此编译器停止查找其他基类。 您可以使用using声明使A::f可见:

class B: public A
{
 public:
  using A::f;
  int f(int x, int y) { return x+y; }
};

如何消除派生类中毫无意义的重载?即使在您的示例中,假设您有一个B实例,您希望禁止使用单参数函数。正如现在所写的,您已经删除了单参数版本(至少在B实例的上下文中从名称解析中删除了它)但是,如果您希望该版本仍然可用,您可以在类中指定
使用A::F;
来引入单参数版本。

我知道发生了什么,我想问的是,为什么该语言设计为在参数数不同时阻止基类查找。@RobertKubrick这与p数无关符号<代码> f>代码>存在于<代码> b>代码>中,默认情况下未查到代码代码> <代码> f>代码>可能是一个变量,同样的事情在这里不存在歧义。当多个被考虑的函数与函数调用同样兼容时,歧义是:在这种情况下,只考虑代码> b::f< /代码>。ed;
A::f
被它隐藏起来。只是一个猜测:默认参数?难道
f(int x,int y=0)
不会像链接答案中解释的那样造成混乱吗?这并没有回答作者的问题。我答案的第一部分解释(简要)名字隐藏在C++中是如何工作的。你能解释一下为什么这不能回答作者的问题吗?@拉萨胡谢谢!在3个回答重复了同样的事情之后,我认为这个问题还不够清楚。“埃洛伦斯用大胆的方式阅读问题部分。”罗伯特库布里克,除非有标准化委员会的回答,我想我们只能猜测。标准很清楚这个特性()第10.2.My 2cts节