473,396 Members | 1,834 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,396 software developers and data experts.

Pure Virtual Function Hiding

A very simple example of something that acts quite odd:

class TopClass
{
public:
TopClass(){ }
virtual ~TopClass(){ }
virtual int myFunc() = 0;
};

class MiddleClass : public TopClass
{
public:
MiddleClass() : TopClass(){ }
virtual ~MiddleClass(){ }
virtual int myFunc( int x ) { return TopClass::myFunc()+x; }
};

class BottomClass : public MiddleClass
{
public:
BottomClass() : MiddleClass(){ }
virtual ~BottomClass(){ }
virtual int myFunc() { return 5; }
};

int
main( int argc, char* argv[] )
{
BottomClass c1;
c1.myFunc( 4 ); //will not compile: "'BottomClass::myFunc' : function
does not take 1 arguments"
return 0;
}

It seems that an instantiation of BottomClass cannot "see" the version
of myFunc that takes an int, declared in MiddleClass. However, both are
public and virtual, so why not?

I'm sure there is some very subtle reason why (probably having to do
with virtual function naming and overloading), but if anyone could
shine some light on this, we'd appreciate it. Some very experienced C++
guys I know have looked at it, without much luck.

Thanks all!

Mar 6 '06 #1
6 2246
Ryan H. wrote:
A very simple example of something that acts quite odd:

class TopClass
{
public:
TopClass(){ }
virtual ~TopClass(){ }
virtual int myFunc() = 0;
};

class MiddleClass : public TopClass
{
public:
MiddleClass() : TopClass(){ }
virtual ~MiddleClass(){ }
virtual int myFunc( int x ) { return TopClass::myFunc()+x; }
};
That looks a bit fishy. TopClass::myFunc is pure virtual.
class BottomClass : public MiddleClass
{
public:
BottomClass() : MiddleClass(){ }
virtual ~BottomClass(){ }
virtual int myFunc() { return 5; }
};

int
main( int argc, char* argv[] )
{
BottomClass c1;
c1.myFunc( 4 ); //will not compile: "'BottomClass::myFunc' : function
does not take 1 arguments"
return 0;
}
Thats right.
It seems that an instantiation of BottomClass cannot "see" the version
of myFunc that takes an int, declared in MiddleClass. However, both are
public and virtual, so why not?


Because the myFunc in BottomClass hides the definition of myFunc in
TopClass (because it's prototype is different). Add a using myFunc to
the BottomClass definition to unhide it.
Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Mar 6 '06 #2
Ryan H. wrote:

I'm sure there is some very subtle reason why (probably having to do
with virtual function naming and overloading), but if anyone could
shine some light on this, we'd appreciate it.


It has nothing to do with virtual. Take out the virtual tags and you'll
have the same problem. (Take out TopClass and you'll have the same
problem, too.)

Overloading only occurs among functions defined in the same scope.
BottomClass only defines one version of myFunc, and it takes no
arguments. End of story.

To get the overloading that you seem to want, hoist MiddleClass::myFunc
into BottomClass with 'using MiddleClass::myFunc'.

--

Pete Becker
Roundhouse Consulting, Ltd.
Mar 6 '06 #3
Ryan H. wrote:
A very simple example of something that acts quite odd:

class TopClass
{
public:
TopClass(){ }
virtual ~TopClass(){ }
virtual int myFunc() = 0;
};

class MiddleClass : public TopClass
{
public:
MiddleClass() : TopClass(){ }
virtual ~MiddleClass(){ }
virtual int myFunc( int x ) { return TopClass::myFunc()+x; }
};

class BottomClass : public MiddleClass
{
public:
BottomClass() : MiddleClass(){ }
virtual ~BottomClass(){ }
virtual int myFunc() { return 5; }
};

int
main( int argc, char* argv[] )
{
BottomClass c1;
c1.myFunc( 4 ); //will not compile: "'BottomClass::myFunc' : function
does not take 1 arguments"
return 0;
}

It seems that an instantiation of BottomClass cannot "see" the version
of myFunc that takes an int, declared in MiddleClass. However, both are
public and virtual, so why not?

I'm sure there is some very subtle reason why (probably having to do
with virtual function naming and overloading), but if anyone could
shine some light on this, we'd appreciate it. Some very experienced C++
guys I know have looked at it, without much luck.


Yes, the name "myFunc" in the BottomClass is said to "hide" the
identical name in the MiddleClass from which it inherits. I believe the
motivation for this behavior is avoid accidentally pulling in some
inherited name that happens to be the same as the one in the local
class that is more likely to be the name which the programmer intended
to reference.

In any case, the programmer can "unhide" the name in the base class
with a using declaration. So adding:

using MiddleClass::MyFunc;

to BottomClass's declaration should unhide MyFunc in the MiddleClass.
Once unhidden, code in the BottomClass should be able to call it.

Greg

Mar 6 '06 #4
Sorry if there was any confusion created over the TopClass::myFunc
reference. The myFunc function in MiddleClass could just read

virtual int myFunc( int x ) { return 5; }

and it would still generate the error. The basic question I have is why
does the myFunc( int ) hide myFunc()? As a side note, adding a pure
virtual myFunc() to TopClass won't help either.

Put another way, in the classic Shapes examples, if there was a pure
virtual draw() function, and I inherited a 3DShape class with a virtual
draw( int perspective ), then my 3DBoxShape class couldn't call 3D's
draw( SIDE ), only the top-level draw().

I understand you can use using to unhide, but you shouldn't have to.
myFunc with the int is a member of MiddleClass, and therefore should
automatically be a member of BottomClass.

Mar 6 '06 #5
Greg wrote:

Once unhidden, code in the BottomClass should be able to call it.


Just a bit of a clarification: code in BottomClass (and code outside it,
talking to a BottomClass object) can call MiddleClass::myFunc, provided
the name is explicitly qualified. In the original example, the
unqualified call doesn't work:

c1.myFunc( 4 ); //will not compile

But this works:

c1.MiddleClass::myFunc( 4 ); // okay

However, adding a using declaration is, of course, almost always the
right answer.

--

Pete Becker
Roundhouse Consulting, Ltd.
Mar 6 '06 #6
Ah, I see now. In my example, BottomClass was hiding MiddleClass's
myFunc. I was getting distracted worrying why it <u>appeared</u>
TopClass was somehow hiding MiddleClass. I understand now. Thanks
everyone for all your help, it was greatly appreciated!

Mar 6 '06 #7

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

Similar topics

11
by: santosh | last post by:
Hello, I was going through the Marshal Cline's C++ FAQ-Lite. I have a doubt regarding section 33.10. Here he is declaring a pure virtual destructor in the base class. And again defining...
6
by: pakis | last post by:
I am having a problem of pure virtual function call in my project. Can anyone explaine me the causes of pure virtual function calls other than calling a virtual function in base class? Thanks
3
by: sudhir | last post by:
I defined a pure virtual function like virtual void sum()=0; <--- pure virtual function but If I defined a virtual function in a base class in case of multilevel inheritance for the base...
21
by: sks | last post by:
Hi , could anyone explain me why definition to a pure virtual function is allowed ?
3
by: Thomas Kowalski | last post by:
Hi everyone, following situation: class A { void m(T value) =0; } class B : A {
10
by: John Goche | last post by:
Hello, page 202 of Symbian OS Explained by Jo Stichbury states "All virtual functions, public, protected or private, should be exported" then page 203 states "In the rare cases where a...
7
by: sam_cit | last post by:
Hi Everyone, I wanted to know as to what is the exact difference between a virtual function and a pure virtual function? Thanks in advance!!!
10
by: Rahul | last post by:
Hi, I tried to create a abstract class by having a non-virtual member function as pure, but i got a compilation error saying "only virtual member functions can be pure"... I'm trying to think...
14
by: Jack | last post by:
Hi, I meet a question with it , I did not get clear the different betteen them, for example: #include <iostream>
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
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,...

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.