C ++继承和名称隐藏 [英] C++ inheritance and name hiding

查看:96
本文介绍了C ++继承和名称隐藏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道,这不是关于该主题的第一个问题,但是据我说,我读过的所有其他相关问题(和答案)都不太合理。
输入代码

I know this is not the first question on this subject, but all the other related questions (and answers) I read were slightly out of the point, according to me. Take the code

#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 ++编译此代码会出现错误

Compiling this code with a recent version of g++ gives the error

no matching function for call to 'Derived::methodA()'

由于这个错误,我来到Stackoverflow上寻找答案。
但是,所有答案都没有使我信服。
两种方法的签名在区分它们时没有任何歧义,编译器应该能够在基类中使用该方法。
只需注释掉

It is because of this error that I came upon Stackoverflow to find an answer. But none of the answers was convincing to me. The signatures of the two methods present no ambiguity in distinguishing them, the compiler should be able to pick up the method in the base class. Just comment out

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

并且代码按预期工作。
这意味着在基类中隐藏相同名称的成员函数只是成员函数名称,并且不考虑签名,例如如果函数名称未修饰(修饰应解决此问题中的任何歧义)案件)。
还有其他人在类似的问题中写道,这违背了C ++的精神(我补充说是面向对象的),我完全同意他的观点。这是函数重载的限制,对此我确实看不到任何合理的原因。

and the code works as expected. This means that it is just the member function name to hide the same name member function in the base class, and the signature is not taken into consideration, like if function names were not mangled (mangling should resolve any ambiguity in this case). Some else wrote in a similar question that this is against the spirit of C++ (and Object Orientation, I add) and I perfectly agree with him. This is a limitation of function overloading for which I really do not see any sound reason.

显然,问题已经关闭,因此我无法添加回复,阅读答案后,除了编辑我自己的初始问题外。
我相当确定(但我无法证明这一点),在较早的C ++编译器中,我最初提出的问题中的代码将毫无问题地进行编译(然后执行)。
我的意思是,我真的看不到该语言设计(在答复中已被称为)背后的原理。在这种情况下,编译器提供了所有信息,以便采取适当的措施,这就是我所期望的。否则,通过语言设计选择,看起来好像没有考虑成员函数的签名,这听起来很奇怪。
我阅读了上面指示的 programmerinterview上的文章,但没有解释是什么促使了语言设计的选择(此外,该文章结尾的示例代码中 GrandChildClass中的 someFunction,如前所述,不会覆盖相同名称的上升类成员函数:两个相同名称的成员函数具有不同的签名-因此不是覆盖)。

Apparently the question has been closed, so I am not able to add a reply, after reading the answers, other than by editing my own initial question. I am fairly sure (but I am not in the position to prove it) that in older C++ compilers the code in my initial question would compile (and then execute) with no problem. My point is that I really do not see the rationale behind that language design (as it has been called in the replies) choice. The compiler, in this case, has available all the information in order to take the proper action, and this is what I would expect. Otherwise it looks like, by language design choice, it has been chosen not to take into consideration the signature of the member functions, which sounds quite weird. I read the article at "programmerinterview" indicated just above, but it does not explain what motivated that language design choice (furthermore, the "someFunction" in the "GrandChildClass" in the example code by the end of that article, does not override, as stated, the same name ascendant class member function: the two same name member functions have different signatures - so it is not an overriding).

推荐答案

这是设计语言的方式-内部作用域中的名称在外部作用域中隐藏名称。在这里,派生类充当内部作用域,而基类充当外部作用域。

That is the way the language is designed - names in inner scopes hide names in outer scopes. Here the derived class acts as an inner scope and the base class as an outer scope.

以下事实:如果函数在相同范围内,则它们将被视为重载,没关系隐藏对名称起作用,而不对单个函数起作用。

The fact that the functions would be considered overloads if they were in the same scope, doesn't matter. The hiding works on the names, not on individual functions.

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

You can override the default, by explicitly adding the name to the derived class:

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

    void methodA(int i) { cout << "Derived.methodA(int i)" << endl ;}
};

这篇关于C ++继承和名称隐藏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆