473,410 Members | 1,953 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,410 software developers and data experts.

Method overloading and inheritance

Hi everyone,

Given the code below, can anyone tell me:
a) Is this normal behaviour ?
b) If it is, what is the reason behind it ? I would expect the
A::method(int) to be inherited by B.

Compiler: gcc 4.1, Linux

Thanks,
Mihai

-----------------------

#include <stdio.h>

class A{
public:
virtual void method(int);
};

class B: public A{
public:
virtual void method();
};

void A::method(int n){
fprintf(stderr, "A::method(%d)\n", n);
}

void B::method(){
fprintf(stderr, "B::method\n");
}

int main(int argc, char** argv){

B b;
b.method(3);
return 0;
}
-----------------

mike@nemesis:~/work/inh_test$ g++ -o main main.cpp
main.cpp: In function 'int main(int, char**)':
main.cpp:31: error: no matching function for call to 'B::method(int)'
main.cpp:18: note: candidates are: virtual void B::method()
Oct 31 '06 #1
10 3343
Mihai Osian wrote:
Hi everyone,

Given the code below, can anyone tell me:
a) Is this normal behaviour ?
b) If it is, what is the reason behind it ? I would expect the
A::method(int) to be inherited by B.

Compiler: gcc 4.1, Linux

Thanks,
Mihai

-----------------------

#include <stdio.h>

class A{
public:
virtual void method(int);
};

class B: public A{
public:
virtual void method();
};
Read about "name hiding" in the FAQ or on Google.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Oct 31 '06 #2
Mihai Osian wrote:
Hi everyone,

Given the code below, can anyone tell me:
a) Is this normal behaviour ?
b) If it is, what is the reason behind it ? I would expect the
A::method(int) to be inherited by B.

Compiler: gcc 4.1, Linux

Thanks,
Mihai

-----------------------

#include <stdio.h>

class A{
public:
virtual void method(int);
};

class B: public A{
public:
virtual void method();
};

void A::method(int n){
fprintf(stderr, "A::method(%d)\n", n);
}

void B::method(){
fprintf(stderr, "B::method\n");
}

int main(int argc, char** argv){

B b;
b.method(3);
return 0;
}
-----------------

mike@nemesis:~/work/inh_test$ g++ -o main main.cpp
main.cpp: In function 'int main(int, char**)':
main.cpp:31: error: no matching function for call to 'B::method(int)'
main.cpp:18: note: candidates are: virtual void B::method()
You haven't over-ridden the virtual function; you have hidden it since
your virtual function in B has a different function signature than that
in A.

Cheers! --M

Oct 31 '06 #3
Mihai Osian wrote:
Hi everyone,

Given the code below, can anyone tell me:
a) Is this normal behaviour ?
b) If it is, what is the reason behind it ? I would expect the
A::method(int) to be inherited by B.

Compiler: gcc 4.1, Linux

Thanks,
Mihai

-----------------------

#include <stdio.h>

class A{
public:
virtual void method(int);
};

class B: public A{
public:
virtual void method();
using A::method;
};
The prototype in B for method() hides all the function in A with the name
"method". You can use the keyword using as above to unhide the functions in A.

--

Adrian
Oct 31 '06 #4
* Mihai Osian:
[rearranged]
>
Given the code below,
-----------------------

#include <stdio.h>

class A{
public:
virtual void method(int);
};

class B: public A{
public:
virtual void method();
};

void A::method(int n){
fprintf(stderr, "A::method(%d)\n", n);
}

void B::method(){
fprintf(stderr, "B::method\n");
}

int main(int argc, char** argv){

B b;
b.method(3);
return 0;
}
-----------------

can anyone tell me:
a) Is this normal behaviour ?
A::method(int) to be inherited by B.
mike@nemesis:~/work/inh_test$ g++ -o main main.cpp
main.cpp: In function 'int main(int, char**)':
main.cpp:31: error: no matching function for call to 'B::method(int)'
main.cpp:18: note: candidates are: virtual void B::method()
Yes, it's normal behavior.

b) If it is, what is the reason behind it ?
Class B's 'method' declaration hides the inherited member function so
that it's not directly accessible.

The inherited member function can still be accessed via an A& or A*
referring to a B object. Or, you can make it available by including

using A::method;

in class B. Or by providing a wrapper in class B.

One rationale that's been put forward is that pure additions to class A,
such as introducing an overload of 'method', should not affect client
code using class B, unless that's explicitly specified in class B.
However, that ignores the fact that a B object is-an A wrt.
polymorphism, and can be referenced via A& or A* (oops, that client
code's still affected by pure additions to A). And it also ignores the
fact that this behavior is highly counter-intuitive, and the fact that
it restricts is-a behavior to runtime polymorphism, not supporting
compile time polymorphism, that is, template code working well with A
may not compile with B (counter-argument is that template code designed
for A may not otherwise necessarily have the intended effect with B (and
counter-counter that that problem is there anyway)).

I would expect the A::method(int) to be inherited by B.
It is; it's just not directly accessible the way the code is currently.

Btw., why don't you just use std::cerr instead of fprintf?
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Oct 31 '06 #5
Mihai Osian wrote:
Given the code below, can anyone tell me:
a) Is this normal behaviour ?
b) If it is, what is the reason behind it ? I would expect the
A::method(int) to be inherited by B.

Compiler: gcc 4.1, Linux

Thanks,
Mihai

-----------------------

#include <stdio.h>

class A{
public:
virtual void method(int);
};

class B: public A{
public:
virtual void method();
};
Overrides must match a signature, which is (roughly) everything from
'method' to the ';'. That includes the int, so you really have two
signatures there. You can test this by independently overloading
method(int).

Next; don't do it. Never willingly give any two things the same name unless
you expressly expect them to override each other. A real-life method(int)
should instead have a deliberately different name.

Your experiment reveals "hiding", where the name of method() in one scope
hides a method with the same name but a different signature in another
scope. That's exactly the same kind of hiding as this:

int x = 42;
{
float x = 42.0;
assert(sizeof (float) = sizeof x);
}
assert(sizeof (int) = sizeof x);

The x in the inner scope hides the one in the outer scope.

--
Phlip
http://www.greencheese.us/ZeekLand <-- NOT a blog!!!
Oct 31 '06 #6

Mihai Osian wrote:
Hi everyone,

Given the code below, can anyone tell me:
a) Is this normal behaviour ?
b) If it is, what is the reason behind it ? I would expect the
A::method(int) to be inherited by B.

Compiler: gcc 4.1, Linux

Thanks,
Mihai

-----------------------

#include <stdio.h>

class A{
public:
virtual void method(int);
};

class B: public A{
public:
virtual void method();
};

void A::method(int n){
fprintf(stderr, "A::method(%d)\n", n);
}

void B::method(){
fprintf(stderr, "B::method\n");
}

int main(int argc, char** argv){

B b;
b.method(3);
return 0;
}
-----------------

mike@nemesis:~/work/inh_test$ g++ -o main main.cpp
main.cpp: In function 'int main(int, char**)':
main.cpp:31: error: no matching function for call to 'B::method(int)'
main.cpp:18: note: candidates are: virtual void B::method()
The member function B::method() hides all/any member functions that A
has with the name method(...), Regardless of the parameters involved
and it doesn't matter whether A::method(..) is virtual or not You could
however, call any version of A::method(..) from within B::method().

void B::method()
{
fprintf(stderr, "B::method\n");
A::method(99);
}

In a case like this, i'ld probably make A::method(int) pure virtual.

Oct 31 '06 #7
Alf P. Steinbach wrote:
* Mihai Osian:
[rearranged]
>>
Given the code below,
-----------------------

#include <stdio.h>

class A{
public:
virtual void method(int);
};

class B: public A{
public:
virtual void method();
};

void A::method(int n){
fprintf(stderr, "A::method(%d)\n", n);
}

void B::method(){
fprintf(stderr, "B::method\n");
}

int main(int argc, char** argv){

B b;
b.method(3);
return 0;
}
-----------------

can anyone tell me:
a) Is this normal behaviour ?
A::method(int) to be inherited by B.
mike@nemesis:~/work/inh_test$ g++ -o main main.cpp
main.cpp: In function 'int main(int, char**)':
main.cpp:31: error: no matching function for call to 'B::method(int)'
main.cpp:18: note: candidates are: virtual void B::method()

Yes, it's normal behavior.
Thanks, apparently everybody knew that, but me :) I've learned something
new today.
>
>b) If it is, what is the reason behind it ?

Class B's 'method' declaration hides the inherited member function so
that it's not directly accessible.

The inherited member function can still be accessed via an A& or A*
referring to a B object. Or, you can make it available by including

using A::method;

in class B. Or by providing a wrapper in class B.

One rationale that's been put forward is that pure additions to class A,
such as introducing an overload of 'method', should not affect client
code using class B, unless that's explicitly specified in class B.
I am not familiar with the term "pure addition", so before I start
arguing I will have to do my Google homework first.

However, that ignores the fact that a B object is-an A wrt.
polymorphism, and can be referenced via A& or A* (oops, that client
code's still affected by pure additions to A). And it also ignores the
fact that this behavior is highly counter-intuitive, and the fact that
it restricts is-a behavior to runtime polymorphism, not supporting
compile time polymorphism, that is, template code working well with A
may not compile with B (counter-argument is that template code designed
for A may not otherwise necessarily have the intended effect with B (and
counter-counter that that problem is there anyway)).
Sorry, you lost me. A concrete example would be more useful. To me,
the current behaviour is counter-intuitive. IMHO any change in the
ancestor class is _supposed_ to change the behaviour of all descendents.
>
>I would expect the A::method(int) to be inherited by B.

It is; it's just not directly accessible the way the code is currently.

Btw., why don't you just use std::cerr instead of fprintf?
Old habbits, I guess. The first thing I learned (long ago) in C/C++
was "printf".
>
Anyway, thanks for the answer. Apparently I think differently than
everybody else. Which probably means I'm wrong :)

Mihai

Oct 31 '06 #8
Phlip wrote:
Mihai Osian wrote:
>Given the code below, can anyone tell me:
a) Is this normal behaviour ?
b) If it is, what is the reason behind it ? I would expect the
A::method(int) to be inherited by B.

Compiler: gcc 4.1, Linux

Thanks,
Mihai

-----------------------

#include <stdio.h>

class A{
public:
virtual void method(int);
};

class B: public A{
public:
virtual void method();
};

Overrides must match a signature, which is (roughly) everything from
'method' to the ';'. That includes the int, so you really have two
signatures there. You can test this by independently overloading
method(int).

Next; don't do it. Never willingly give any two things the same name unless
you expressly expect them to override each other. A real-life method(int)
should instead have a deliberately different name.

Actually, I have to write C++ wrapper classes around JNI calls (Java
Native Intefaces), which will mirror the functionality of the Java peer
classes.
The Java classes are organized in the way I described, so it is not
really my decision.

>
Your experiment reveals "hiding", where the name of method() in one scope
hides a method with the same name but a different signature in another
scope. That's exactly the same kind of hiding as this:

int x = 42;
{
float x = 42.0;
assert(sizeof (float) = sizeof x);
}
assert(sizeof (int) = sizeof x);

The x in the inner scope hides the one in the outer scope.
I don't think your argument is valid. In your outer scope there can
be only one "x" variable. In my "outer scope" - class A, there can be
any number of "method"s, with different signatures.
What you probably mean is that overloaded methods are just "flavours"
of a single function, so I should either overload them all, or overload
none. Except that I don't agree with this point of view. By the way -
the people who designed Java seem to share my opinion. Please, please, I
don't want to start a Java versus C++ flamewar. I am a C++ developer, it
just happens that I agree with the Java approach on this one.

Mihai






Oct 31 '06 #9
Mihai Osian wrote:
What you probably mean is that overloaded methods are just "flavours"
of a single function, so I should either overload them all, or overload
none. Except that I don't agree with this point of view. By the way -
the people who designed Java seem to share my opinion. Please, please, I
don't want to start a Java versus C++ flamewar. I am a C++ developer, it
just happens that I agree with the Java approach on this one.
If you are writing C++ code you must agree with the C++ standard. Trying to
change it will take several years, in the best case.

--
Salu2
Oct 31 '06 #10

Mihai Osian wrote:
Phlip wrote:
Mihai Osian wrote:
Given the code below, can anyone tell me:
a) Is this normal behaviour ?
b) If it is, what is the reason behind it ? I would expect the
A::method(int) to be inherited by B.

Compiler: gcc 4.1, Linux

Thanks,
Mihai

-----------------------

#include <stdio.h>

class A{
public:
virtual void method(int);
};

class B: public A{
public:
virtual void method();
};
Overrides must match a signature, which is (roughly) everything from
'method' to the ';'. That includes the int, so you really have two
signatures there. You can test this by independently overloading
method(int).

Next; don't do it. Never willingly give any two things the same name unless
you expressly expect them to override each other. A real-life method(int)
should instead have a deliberately different name.


Actually, I have to write C++ wrapper classes around JNI calls (Java
Native Intefaces), which will mirror the functionality of the Java peer
classes.
The Java classes are organized in the way I described, so it is not
really my decision.
Actually I don't think the advice there is the best. Use of the same
name isn't in and of itself a problem, but using the same name to do a
different things is confusing for people using the classes.

Hopefully the Java design you have to copy follows this with the
differing arguments reflecting differing situations where you want to
do the same thing. If it doesn't then the classes are probably a lot
harder to understand than they should be.
>

Your experiment reveals "hiding", where the name of method() in one scope
hides a method with the same name but a different signature in another
scope. That's exactly the same kind of hiding as this:

int x = 42;
{
float x = 42.0;
assert(sizeof (float) = sizeof x);
}
assert(sizeof (int) = sizeof x);

The x in the inner scope hides the one in the outer scope.

I don't think your argument is valid. In your outer scope there can
be only one "x" variable. In my "outer scope" - class A, there can be
any number of "method"s, with different signatures.
What you probably mean is that overloaded methods are just "flavours"
of a single function, so I should either overload them all, or overload
none. Except that I don't agree with this point of view. By the way -
the people who designed Java seem to share my opinion. Please, please, I
don't want to start a Java versus C++ flamewar. I am a C++ developer, it
just happens that I agree with the Java approach on this one.
Actually there is no real reason to overload either all or none. This
depends on the design of the classes and what the methods should be
doing. C++ like Java makes no rule about how you should do this.

What is different though are the rules for exposing the names in
sub-classes and the syntax for dealing with it. Not unreasonable. What
you want to add to your class B is this:

using A::method;

This pulls all of the methods called 'method' from A and makes them
available to B and you can then add or change them as you want. I
suppose you might consider this done automatically in Java, but it
isn't in C++.
K

Nov 1 '06 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

17
by: Terje Slettebø | last post by:
To round off my trilogy of "why"'s about PHP... :) If this subject have been discussed before, I'd appreciate a pointer to it. I again haven't found it in a search of the PHP groups. The PHP...
1
by: Fuzzyman | last post by:
I've been programming in python for a few months now - and returning to programming after a gap of about ten years I've really enjoyed learning python. I've just made my first forays into...
4
by: Dave Theese | last post by:
Hello all, I'm trying to get a grasp of the difference between specializing a function template and overloading it. The example below has a primary template, a specialization and an overload. ...
19
by: jacob navia | last post by:
C++ introduced an interesting feature (among others): operator overloading. The idea is to build a mechanism for the user defining its own number types and the operations to be done with them. ...
6
by: apm | last post by:
Recently I have had to use a value type for a complex structure because I don't know how to override the = operator. Can the operator ever be overloaded? Or can inheritance be used with value types?
6
by: Massimo Soricetti | last post by:
Hello, recently I wrote a little class which has to wrap two different type of data, showing the same external interface. I used operator overloading, but the same result I could eventually...
11
by: placid | last post by:
Hi all, Is it possible to be able to do the following in Python? class Test: def __init__(self): pass def puts(self, str): print str
0
by: David Boddie | last post by:
On Mon May 26 17:37:04 CEST 2008, Alex Gusarov wrote: Right. I vaguely remember someone showing something like this at EuroPython a couple of years ago. I believe that this approach is actually...
3
by: puzzlecracker | last post by:
Are static method inheritable under csharp rules, if so how can they be used? Can they be virtual? They reason I am asking is because operators are static, and I don't understand how can we...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.