C++继承和名称隐藏

use*_*321 2 c++ inheritance name-hiding

据我所知,我知道这不是关于这个问题的第一个问题,但我读到的所有其他相关问题(和答案)都略显不合适.拿代码

#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();
}
Run Code Online (Sandbox Code Playgroud)

使用最新版本的g ++编译此代码会产生错误

no matching function for call to 'Derived::methodA()'
Run Code Online (Sandbox Code Playgroud)

正是因为这个错误,我才想到Stackoverflow找到答案.但是没有一个答案对我有说服力.这两种方法的签名在区分它们时没有任何歧义,编译器应该能够在基类中获取方法.只是评论出来

class Derived : public Base {
//public:
//    void methodA(int i) { cout << "Derived.methodA(int i)" << endl ;}
};
Run Code Online (Sandbox Code Playgroud)

并且代码按预期工作.这意味着它只是成员函数名称在基类中隐藏相同的名称成员函数,并且不考虑签名,例如函数名称没有被修改(在这种情况下,修改应该解决任何歧义).其他一些人在一个类似的问题中写道,这违背了C++的精神(以及我添加的面向对象),我完全赞同他.这是函数重载的限制,我真的看不出任何合理的原因.

显然问题已经关闭,所以除了编辑我自己的初始问题之外,我无法在阅读答案后添加回复.我相当肯定(但我不能证明它)在旧的C++编译器中,我的初始问题中的代码将编译(然后执行)没有问题.我的观点是,我真的没有看到语言设计背后的理由(正如在回复中所说的那样).在这种情况下,编译器可以获取所有信息以便采取适当的操作,这就是我所期望的.否则看起来,通过语言设计选择,它被选择不考虑成员函数的签名,这听起来很奇怪.我在上面指出的"programmerinterview"中读到了这篇文章,

Bo *_*son 5

这就是语言的设计方式 - 内部作用域中的名称隐藏了外部作用域中的名称.这里派生类充当内部范围,基类充当外部范围.

如果函数在相同的范围内被认为是重载的事实并不重要.隐藏在名称上,而不是在单个函数上.

您可以通过将名称显式添加到派生类来覆盖默认值:

class Derived : public Base {
public:
    using Base::methodA;   // Now it is visible!

    void methodA(int i) { cout << "Derived.methodA(int i)" << endl ;}
};
Run Code Online (Sandbox Code Playgroud)

  • 可能想澄清类层次结构中"内部"和"外部"范围的含义. (2认同)

JSF*_*JSF 2

这意味着仅仅通过成员函数名来隐藏基类中的同名成员函数,而不考虑签名

正确的。这就是语言的设计方式。我也不太喜欢这种语言设计功能。但它有充分的记录,你别无选择。