Overloading, hiding, :: and virtuals

O

Ole Nielsby

I'm puzzed by this:

/***code begin***/
class X {};
class Y : public X {};

class A {
public: virtual void m(X x) {std::wcout << L"A\n";}
};
class B : public A {
public: void m(Y y) {std::wcout << L"B\n";}
};
class C : public B {
public: void m(X x) {std::wcout << L"C\n";}
};

void headache()
{
X x;
B *b = new C();

// b->m(x); //won't compile
b->A::m(x); // outputs A
((A*)b)->m(x); // outputs C
};

/***code end***/

Why does B::m(Y) hide A::m(X)?
Is this a VC quirk or is it a C++ standard thing, and in
that case, what's the rationale? I would expect the public
declaration of A::m to be like part of B insofar as B
doesn't redefine m(X).

When I discovered the b->m(x) wouldn't compile, my
first workaround was b->A::m(x); I assumed this was
the way to tell the compiler not to let the B::m(Y) declaration
distract from the A::m(X); but as the example shows, this
has the side effect of disabling the virtual lookup, which
is not what I intended.

So I finally got to ((A*)b)->m(x); but it aint' handsome...

Is this what I'm supposed to write, or am I not supposed
to overload different signatures of the same method name
in different levels? It does make sense to do this in my
project, I stumbled on the problem by accident, not
because i was trying to push the limits of C++.
 
K

Kai-Uwe Bux

Ole said:
class X {};
class Y : public X {};

class A {
public: virtual void m(X x) {std::wcout << L"A\n";}
};
class B : public A {
public:

insert:

using A::m;
void m(Y y) {std::wcout << L"B\n";}
};
class C : public B {
public: void m(X x) {std::wcout << L"C\n";}
};

void headache()
{
X x;
B *b = new C();

// b->m(x); //won't compile

now it should.
b->A::m(x); // outputs A
((A*)b)->m(x); // outputs C
};



Best

Kai-Uwe Bux
 
G

Gianni Mariani

Ole said:
I'm puzzed by this:
....

...
I stumbled on the problem by accident, not
because i was trying to push the limits of C++.

Yes, I am not sure why the C++ gods thought that it was a good idea to
hide inherited functions with the same name. But it is so.

However, the "using" keyword can "unhide" it for you.

(Note that MSVC 2003 breaks on this.).

struct X;
struct Y;

struct A
{
void f( X* );
};

struct B : A
{
using A::f;
void f( Y* );
};

int main()
{
X*x;
Y*y;
B b;

b.f(x);
b.f(y);
}

The alternative is to add a function in B that delegates to the function
in A.
 
M

Marcus Kwok

Ole Nielsby said:
I'm puzzed by this:

/***code begin***/
class X {};
class Y : public X {};

class A {
public: virtual void m(X x) {std::wcout << L"A\n";}
};
class B : public A {
public: void m(Y y) {std::wcout << L"B\n";}
};
class C : public B {
public: void m(X x) {std::wcout << L"C\n";}
};

void headache()
{
X x;
B *b = new C();

// b->m(x); //won't compile
b->A::m(x); // outputs A
((A*)b)->m(x); // outputs C
};

/***code end***/

Why does B::m(Y) hide A::m(X)?

See:
http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9
 
O

Ole Nielsby

Gianni Mariani said:
...
Yes, I am not sure why the C++ gods thought that it was a good
idea to hide inherited functions with the same name. But it is so.

We mortals must humbly bow to the gods and accept that we do
not always understand their ways. However I promise I won't
do this thing to you, should my own PILS programming system
(which has forced me to learn C++ because I need to implement
it on common ground between Redmond and Tuxistan) succeed
in making me immortal. I have other tricks in my bag to stun you,
but not this one.
However, the "using" keyword can "unhide" it for you.

(Note that MSVC 2003 breaks on this.).

Luckily, it works in MSVC 2005 which is what I am using
for the time being - and it works with virtuals, too, though
I am not at easy with the notation:
using Baseclass::method;
since Baseclass::method(...) usually disables the virtual
lookup, it isn't obvious that the using...::... respects virtuals.

Anyway, thanks for helping me out. I'm glad to know I'm
not the first to be puzzled by this feature.
 

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

Forum statistics

Threads
473,756
Messages
2,569,533
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top