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

Overloading, hiding, :: and virtuals

P: n/a
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++.
Sep 27 '06 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Ole Nielsby wrote:
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
Sep 27 '06 #2

P: n/a
Ole Nielsby wrote:
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.
Sep 28 '06 #3

P: n/a
Ole Nielsby <ol*********@snailmail.dkwrote:
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-lit....html#faq-23.9

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Sep 28 '06 #4

P: n/a
Gianni Mariani <gi*******@mariani.wswrote
Ole Nielsby wrote:
>I'm puzzed by this:
...
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.
Sep 28 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.