C++ inheritance and name hiding [duplicate]

我是研究僧i 提交于 2020-01-24 09:28:23

问题


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();
}

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

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

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 ;}
};

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.

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).


回答1:


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 ;}
};



回答2:


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

Correct. That is the way the language was designed. I don't really like that language design feature either. But it is well documented and you don't have a choice.




回答3:


I think you already understood. Its called Name Hiding and this is how the language is made. But i don't see it as an inconvenience as you get pretty comfortable with these convention eventually when you spend time with C++. When you define a non virtual method with the same name as Base method it hides the Base class method in Derived class so you are getting the error for

obj.methodA();

To avoid hiding of Base class methods in Derived class, you can do :

obj.Base::methodA();

For more info: http://www.programmerinterview.com/index.php/c-cplusplus/c-name-hiding/



来源:https://stackoverflow.com/questions/32946364/c-inheritance-and-name-hiding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!