【发布时间】:2016-01-01 23:27:44
【问题描述】:
我知道这不是关于这个主题的第一个问题,但据我说,我读到的所有其他相关问题(和答案)都有些不合时宜。 拿代码
#include <iostream>
using namespace std ;
class Base {
public:
void methodA() { cout << "Base.methodA()" << endl ;}
};
class Derived : public Base {
public:
void methodA(int i) { cout << "Derived.methodA(int i)" << endl ;}
};
int main()
{
Derived obj;
obj.methodA();
}
使用最新版本的 g++ 编译此代码会出现错误
no matching function for call to 'Derived::methodA()'
正是因为这个错误,我才来到 Stackoverflow 寻找答案。 但没有一个答案让我信服。 这两种方法的签名在区分它们时没有歧义,编译器应该能够在基类中选择方法。 注释掉
class Derived : public Base {
//public:
// void methodA(int i) { cout << "Derived.methodA(int i)" << endl ;}
};
并且代码按预期工作。 这意味着在基类中隐藏同名成员函数只是成员函数名称,并且不考虑签名,就像函数名称没有被修改一样(在这种情况下,修改应该解决任何歧义)。 其他人在类似的问题中写道,这违背了 C++ 的精神(以及我补充说的面向对象),我完全同意他的观点。这是函数重载的一个限制,我真的没有看到任何合理的理由。
显然问题已关闭,所以我无法在阅读答案后添加回复,只能编辑我自己的初始问题。 我相当肯定(但我无法证明这一点)在较旧的 C++ 编译器中,我最初问题中的代码可以毫无问题地编译(然后执行)。 我的观点是,我真的看不出这种语言设计(正如回复中所说的那样)选择背后的基本原理。在这种情况下,编译器已经获得了所有信息,以便采取适当的措施,这正是我所期望的。否则看起来,通过语言设计选择,它被选择不考虑成员函数的签名,这听起来很奇怪。 我在上面提到的“programmerinterview”上阅读了这篇文章,但它没有解释是什么促使了这种语言设计选择(此外,该文章末尾示例代码中的“GrandChildClass”中的“someFunction”不会覆盖,如前所述,同名的上升类成员函数:两个同名的成员函数具有不同的签名 - 所以它不是覆盖)。
【问题讨论】:
-
这似乎更像是一个咆哮而不是一个问题。在这种情况下,您似乎了解 C++ 的行为。
-
换一种说法,其他人可能会说这是函数重载的一个优势......这是语言在一天结束时定义的内容。
-
投票重新开放。如果有人有一本旧书,他们可以找到有关它的报价。作为记录,我认为被拒绝的不良行为和当前规范都略有偏差。我想他有可能曾经有一个编译器做我希望标准做的事情,那就是匹配传递的参数数量。
-
stroustrup.com/bs_faq2.html#overloadderived 解释了为什么它需要以这种方式工作。
标签: c++ inheritance name-hiding