Simple polymorphism question

  • Thread starter Soren Holstebroe
  • Start date
S

Soren Holstebroe

Hi lang.c++,

Having programmed in Java for quite a while now I was a bit surprised when
the following c++ construction didn't compile:

--------------------
#include <iostream>

class A {
public:
void f() {
std::cout << "Foo" << std::endl;
}
};

class B : public A {
public:
void f(int i) {
std::cout << "Bar = " << i << std::endl;
}
};

int main() {
B b;
b.f();
b.f(5);
return 0;
}
-------------------
bash-2.05b$ g++ --version
g++ (GCC) 3.3.5 (Gentoo Linux 3.3.5-r1, ssp-3.3.2-3, pie-8.7.7.1)
bash-2.05b$ g++ polym.cc
polym.cc: In function `int main()':
polym.cc:18: error: no matching function for call to `B::f()'
polym.cc:11: error: candidates are: virtual void B::f(int)
-------------------
Can someone enlighten me why method overloading is not possible in this
case ?

--
Søren Holstebroe
Scientific Programmer
e: (e-mail address removed)
w: http://www.wjc.ku.dk
p: +45 353 27819
 
J

John Carson

Soren Holstebroe said:
Hi lang.c++,

Having programmed in Java for quite a while now I was a bit surprised
when the following c++ construction didn't compile:

--------------------
#include <iostream>

class A {
public:
void f() {
std::cout << "Foo" << std::endl;
}
};

class B : public A {
public:
void f(int i) {
std::cout << "Bar = " << i << std::endl;
}
};

int main() {
B b;
b.f();
b.f(5);
return 0;
}
-------------------
bash-2.05b$ g++ --version
g++ (GCC) 3.3.5 (Gentoo Linux 3.3.5-r1, ssp-3.3.2-3, pie-8.7.7.1)
bash-2.05b$ g++ polym.cc
polym.cc: In function `int main()':
polym.cc:18: error: no matching function for call to `B::f()'
polym.cc:11: error: candidates are: virtual void B::f(int)

Declaring a function named f in the derived class hides all functions of the
same name in the base class even if they have different arguments. You can
resolve the problem with a using declaration:

class B : public A {
public:
using A::f;
void f(int i) {
std::cout << "Bar = " << i << std::endl;
}
};
 
J

Jeremiah L.Jiang

b.f() will not work. Because the compiler will obscur the base class's
f function.
 
K

Karl Heinz Buchegger

Soren said:
Hi lang.c++,

Having programmed in Java for quite a while now I was a bit surprised when
the following c++ construction didn't compile:

--------------------
#include <iostream>

class A {
public:
void f() {

This introduces a function called 'f'
std::cout << "Foo" << std::endl;
}
};

class B : public A {
public:
void f(int i) {

This function 'f' hides all functions with the same name
in the base class.
std::cout << "Bar = " << i << std::endl;
}
};

What you observe is called hiding.
Basically it means: A member function hides all functions with
the same name in the base class(es).
It is a direct consequence how function lookup is implemented
in C++: First search the class which has that function based on
the function name. Then search that class, which one of possibly
many functions with that name match in the argument types.

You can bring the base class member function in scope again
with a 'using' directive:

class B : public A {
public:

using A::f; // This tells the compiler: all functions f from A
// are also valid candidates.

void f(int i) {
...
};
 
F

flyaflya

you should use "virtual", neither can modify param num

class A {
public:
virtual void f(int i) {
std::cout << "Foo" << std::endl;
}
};

class B : public A {
public:
virtual void f(int i) {
std::cout << "Bar = " << i << std::endl;
}
};
 
F

flyaflya

you should use "virtual", neither can modify param num

class A {
public:
virtual void f(int i) {
std::cout << "Foo" << std::endl;
}
};

class B : public A {
public:
virtual void f(int i) {
std::cout << "Bar = " << i << std::endl;
}
};
 
S

Soren Holstebroe

Making f() virtual doesn't help. I'm not trying to overwrite the behavior of
f in the derived class. I want to define an alternative parameter list to
f() in the derived class. The solution is to use the using directive or
alternative naming. IMHO c++ has many ugly counterintuitive design
decisions. I'm sure the ARM has some good argumentation of why hiding is a
good thing, but to me it's annoying. However, I solved my problem with
alternative naming, which in my case probably turns out to be a more
intuitive thing than name overloading.

Søren
 
M

Mark P

Soren said:
Making f() virtual doesn't help. I'm not trying to overwrite the behavior of
f in the derived class. I want to define an alternative parameter list to
f() in the derived class. The solution is to use the using directive or
alternative naming. IMHO c++ has many ugly counterintuitive design
decisions. I'm sure the ARM has some good argumentation of why hiding is a
good thing, but to me it's annoying. However, I solved my problem with
alternative naming, which in my case probably turns out to be a more
intuitive thing than name overloading.

Søren

Please don't top post (i.e., place your replies below those to which
you're replying).

Also, it may be counterintuitive to you but there are reasons for this
decision. Most commonly cited, I believe, is that in a complex
hierarchy, clients of a derived class may not be fully aware of the
details of a far removed base class. What a pity it would be to have an
unexpected type cast (or even just a typo) invoke a function of whose
existence the client was completely unaware. C++ provides an easy way
to override this behavior (the using directive) and allows the compiler
to catch potential errors otherwise.

- Mark
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,202
Messages
2,571,057
Members
47,661
Latest member
sxarexu

Latest Threads

Top