Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function with same name but different signature in derived class

I have a function with the same name, but with different signature in a base and derived classes. When I am trying to use the base class's function in another class that inherits from the derived, I receive an error. See the following code:

class A {     public:     void foo(string s){}; };  class B : public A {     public:     int foo(int i){}; };  class C : public B {     public:     void bar()     {         string s;         foo(s);     } }; 

I receive the following error from the gcc compiler:

In member function `void C::bar()': no matching function for call to `C::foo(std::string&)' candidates are: int B::foo(int) 

If I remove int foo(int i){}; from class B, or if I rename it from foo1, everything works fine.

What's the problem with this?

like image 899
Igor Avatar asked Jan 04 '09 15:01

Igor


People also ask

Is possible when a derived class function has the same name and signature?

Explanation: Function overriding is possible when a derived class function has the same name and signature as its base class.

Which of the following function can be overridden in derived class with the same signature?

Virtual functions are functions that can be overridden in derived class with the same signature.

Can different classes have member functions with the same name?

You can not modify a class after it has been declared and you can not declare two different classes with the same name.


1 Answers

It is because name lookup stops if it finds a name in one of your bases. It won't look beyond in other bases. The function in B shadows the function in A. You have to re-declare the function of A in the scope of B, so that both functions are visible from within B and C:

class A {     public:     void foo(string s){}; };  class B : public A {     public:     int foo(int i){};     using A::foo; };  class C : public B {     public:     void bar()     {         string s;         foo(s);     } }; 

Edit: The real description the Standard gives is (from 10.2/2):

The following steps define the result of name lookup in a class scope, C. First, every declaration for the name in the class and in each of its base class sub-objects is considered. A member name f in one sub- object B hides a member name f in a sub-object A if A is a base class sub-object of B. Any declarations that are so hidden are eliminated from consideration. Each of these declarations that was introduced by a using-declaration is considered to be from each sub-object of C that is of the type containing the declara- tion designated by the using-declaration.96) If the resulting set of declarations are not all from sub-objects of the same type, or the set has a nonstatic member and includes members from distinct sub-objects, there is an ambiguity and the program is ill-formed. Otherwise that set is the result of the lookup.

It has the following to say in another place (just above it):

For an id-expression [something like "foo"], name lookup begins in the class scope of this; for a qualified-id [something like "A::foo", A is a nested-name-specifier], name lookup begins in the scope of the nested-name-specifier. Name lookup takes place before access control (3.4, clause 11).

([...] put by me). Note that means that even if your foo in B is private, the foo in A will still not be found (because access control happens later).

like image 182
Johannes Schaub - litb Avatar answered Nov 04 '22 15:11

Johannes Schaub - litb