Connecting Tech Pros Worldwide Help | Site Map
 
 
LinkBack Thread Tools Search this Thread
  #1  
Old September 28th, 2006, 12:05 AM
Ole Nielsby
Guest
 
Posts: n/a
Default Overloading, hiding, :: and virtuals

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++.


  #2  
Old September 28th, 2006, 12:45 AM
Kai-Uwe Bux
Guest
 
Posts: n/a
Default Re: Overloading, hiding, :: and virtuals

Ole Nielsby wrote:
Quote:
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;
Quote:
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.
Quote:
b->A::m(x); // outputs A
((A*)b)->m(x); // outputs C
};
>


Best

Kai-Uwe Bux
  #3  
Old September 28th, 2006, 01:45 AM
Gianni Mariani
Guest
 
Posts: n/a
Default Re: Overloading, hiding, :: and virtuals

Ole Nielsby wrote:
Quote:
I'm puzzed by this:
....

...
I stumbled on the problem by accident, not
Quote:
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.
  #4  
Old September 28th, 2006, 06:15 PM
Marcus Kwok
Guest
 
Posts: n/a
Default Re: Overloading, hiding, :: and virtuals

Ole Nielsby <ole.nielsby@snailmail.dkwrote:
Quote:
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
  #5  
Old September 29th, 2006, 12:05 AM
Ole Nielsby
Guest
 
Posts: n/a
Default Re: Overloading, hiding, :: and virtuals

Gianni Mariani <gi3nospam@mariani.wswrote
Quote:
Ole Nielsby wrote:
Quote:
>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.
Quote:
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.


 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 205,338 network members.