By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,903 Members | 1,184 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,903 IT Pros & Developers. It's quick & easy.

Inheritance not letting signature to come through.

P: n/a
Hi, I was posed this question and I didn't know the answer. Anybody
here know why a member function of the same name but different signature
from that of a class it inherits from is not viable unless explicitly
made so using the 'using' keyword?

Here is an example:

1 class C1
2 {
3 public:
4 void M1(int i) {}
5 };
6
7
8 class C2: public C1
9 {
10 public:
11 // using C1::M1; //< When commented, g++ and VC++ emit error
12 void M1(int i, int j) {}
13 };
14
15 int main()
16 {
17 C2 c;
18 c.M1(14); //< Error emitted here
19 c.M1(1, 2);
20 return 0;
21 }

g++ emits:
18: error: no matching function for call to `C2::M1(int)'
12: note: candidates are: void C2::M1(int, int)

Thanks,
Adrian

--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ _---_ Q. What are you doing here? _---_ /
\ / | A. Just surf'n the net, teaching and | \ /
\__/___\___ learning, learning and teaching. You?_____/___\__/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
May 25 '07 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Adrian Hawryluk wrote:
Hi, I was posed this question and I didn't know the answer. Anybody
here know why a member function of the same name but different signature
from that of a class it inherits from is not viable unless explicitly
made so using the 'using' keyword?

Here is an example:

1 class C1
2 {
3 public:
4 void M1(int i) {}
5 };
6
7
8 class C2: public C1
9 {
10 public:
11 // using C1::M1; //< When commented, g++ and VC++ emit error
12 void M1(int i, int j) {}
13 };
14
15 int main()
16 {
17 C2 c;
18 c.M1(14); //< Error emitted here
19 c.M1(1, 2);
20 return 0;
21 }

g++ emits:
18: error: no matching function for call to `C2::M1(int)'
12: note: candidates are: void C2::M1(int, int)

Because the standard says so in 10.2.2:
"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."

Someone around here probably knows the actual justification for that
being in the standard.

--
Alan Johnson
May 25 '07 #2

P: n/a
On May 25, 7:29 pm, Alan Johnson <a...@yahoo.comwrote:
Adrian Hawryluk wrote:
Hi, I was posed this question and I didn't know the answer. Anybody
here know why a member function of the same name but different signature
from that of a class it inherits from is not viable unless explicitly
made so using the 'using' keyword?
Here is an example:
1 class C1
2 {
3 public:
4 void M1(int i) {}
5 };
8 class C2: public C1
9 {
10 public:
11 // using C1::M1; //< When commented, g++ and VC++ emit error
12 void M1(int i, int j) {}
13 };
15 int main()
16 {
17 C2 c;
18 c.M1(14); //< Error emitted here
19 c.M1(1, 2);
20 return 0;
21 }
g++ emits:
18: error: no matching function for call to `C2::M1(int)'
12: note: candidates are: void C2::M1(int, int)
Because the standard says so in 10.2.2:
"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."
Someone around here probably knows the actual justification for that
being in the standard.
One possible reason is so that adding functions to the base
class won't break the derived class. Consider something like:

class Base
{
} ;

class Derived : public Base
{
public:
void f( int i ) { /* ... */ }
void g( char c ) { /* ... */ ; f( c ) ; /* ... */ }
} ;

What happens now if you add a function "void f( int )" to base?
May 25 '07 #3

P: n/a
James Kanze wrote:
On May 25, 7:29 pm, Alan Johnson <a...@yahoo.comwrote:
>Because the standard says so in 10.2.2:
"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."
>Someone around here probably knows the actual justification for that
being in the standard.

One possible reason is so that adding functions to the base
class won't break the derived class. Consider something like:

class Base
{
} ;

class Derived : public Base
{
public:
void f( int i ) { /* ... */ }
void g( char c ) { /* ... */ ; f( c ) ; /* ... */ }
} ;

What happens now if you add a function "void f( int )" to base?

In this case, without 10.2.2, you would have an ambiguity but I think
adding a function "void f( char )" to the base makes the potential issue
even more obviously horrible, as you now have a better match in the base
class, changing the behaviour of Derived with (theoretically) no
compiler warning.
May 26 '07 #4

P: n/a
James Kanze wrote:
On May 25, 7:29 pm, Alan Johnson <a...@yahoo.comwrote:
>Adrian Hawryluk wrote:
>>Hi, I was posed this question and I didn't know the answer. Anybody
here know why a member function of the same name but different signature
from that of a class it inherits from is not viable unless explicitly
made so using the 'using' keyword?
>>Here is an example:
>> 1 class C1
2 {
3 public:
4 void M1(int i) {}
5 };
>> 8 class C2: public C1
9 {
10 public:
11 // using C1::M1; //< When commented, g++ and VC++ emit error
12 void M1(int i, int j) {}
13 };
>> 15 int main()
16 {
17 C2 c;
18 c.M1(14); //< Error emitted here
19 c.M1(1, 2);
20 return 0;
21 }
>>g++ emits:
18: error: no matching function for call to `C2::M1(int)'
12: note: candidates are: void C2::M1(int, int)
>Because the standard says so in 10.2.2:
"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."
>Someone around here probably knows the actual justification for that
being in the standard.

One possible reason is so that adding functions to the base
class won't break the derived class. Consider something like:

class Base
{
} ;

class Derived : public Base
{
public:
void f( int i ) { /* ... */ }
void g( char c ) { /* ... */ ; f( c ) ; /* ... */ }
} ;

What happens now if you add a function "void f( int )" to base?

Since in the call to g, this is a Derived*, would this not just call
Derived::f(int)?

That is not scary at all.
Adrian
--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ _---_ Q. What are you doing here? _---_ /
\ / | A. Just surf'n the net, teaching and | \ /
\__/___\___ learning, learning and teaching. You?_____/___\__/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
May 26 '07 #5

P: n/a
Charles Bailey wrote:
James Kanze wrote:
>On May 25, 7:29 pm, Alan Johnson <a...@yahoo.comwrote:
>>Because the standard says so in 10.2.2:
"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."
>>Someone around here probably knows the actual justification for that
being in the standard.

One possible reason is so that adding functions to the base
class won't break the derived class. Consider something like:

class Base
{
} ;

class Derived : public Base
{
public:
void f( int i ) { /* ... */ }
void g( char c ) { /* ... */ ; f( c ) ; /* ... */ }
} ;

What happens now if you add a function "void f( int )" to base?


In this case, without 10.2.2, you would have an ambiguity but I think
adding a function "void f( char )" to the base makes the potential issue
even more obviously horrible, as you now have a better match in the base
class, changing the behaviour of Derived with (theoretically) no
compiler warning.
That I can see as a problem. Thanks.
Adrian
--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ _---_ Q. What are you doing here? _---_ /
\ / | A. Just surf'n the net, teaching and | \ /
\__/___\___ learning, learning and teaching. You?_____/___\__/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
May 26 '07 #6

P: n/a
On May 26, 1:56 am, Charles Bailey <usenetspa...@hashpling.orgwrote:
James Kanze wrote:
On May 25, 7:29 pm, Alan Johnson <a...@yahoo.comwrote:
Because the standard says so in 10.2.2:
"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."
Someone around here probably knows the actual justification for that
being in the standard.
One possible reason is so that adding functions to the base
class won't break the derived class. Consider something like:
class Base
{
} ;
class Derived : public Base
{
public:
void f( int i ) { /* ... */ }
void g( char c ) { /* ... */ ; f( c ) ; /* ... */ }
} ;
What happens now if you add a function "void f( int )" to base?
In this case, without 10.2.2, you would have an ambiguity but I think
adding a function "void f( char )" to the base makes the potential issue
even more obviously horrible, as you now have a better match in the base
class, changing the behaviour of Derived with (theoretically) no
compiler warning.
Yes. That's actually the example that I meant to post. Adding
the function to Base silently causes the semantics of
Derived:g() to change.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
May 26 '07 #7

P: n/a
On May 26, 1:16 pm, Adrian Hawryluk <adrian.hawryluk-at-
gmail....@nospam.comwrote:
James Kanze wrote:
On May 25, 7:29 pm, Alan Johnson <a...@yahoo.comwrote:
Adrian Hawryluk wrote:
[...]
Because the standard says so in 10.2.2:
"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."
Someone around here probably knows the actual justification for that
being in the standard.
One possible reason is so that adding functions to the base
class won't break the derived class. Consider something like:
class Base
{
} ;
class Derived : public Base
{
public:
void f( int i ) { /* ... */ }
void g( char c ) { /* ... */ ; f( c ) ; /* ... */ }
} ;
What happens now if you add a function "void f( int )" to base?
Since in the call to g, this is a Derived*, would this not just call
Derived::f(int)?
Sorry. The added function should have been void Base::f(char).
If both Base::f(char) and Derived::f(int) were available,
overload resolution will pick up the first when calling f() with
a char. This results in a silent change in the semantics of
Derived::g().

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

May 26 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.