Why do I get this C++ warning?

147 views
Skip to first unread message

Greg Manning

unread,
Dec 2, 1995, 3:00:00 AM12/2/95
to
In CW7, when "extended error checking" is on, the following program
generates a warning.

Warning : function declaration hides inherited virtual function
CBaseAndSub.cp line 18 void Foo(int a);

As far as I can tell, this warning is unmeritted. Now, I know that
deciding when to generate warnings is a bit tricky since there are many
perfectly legal C++ programs that contain dubious constructs. I would
like to write code that avoids dubious constructs but I can't see what the
dubious construct is that this warning is referring to. So, I'm inclined
to think that this warning "should" not be generated...
=============================================
#include "Types.h"

// if this is defined to 1, no warning is generated
#define CSubFooVoid 0

class CBase
{
public:
virtual void Foo(void);
};

class CSub : public CBase
{
public:
#if CSubFooVoid
void Foo(void);
#endif
void Foo(int a);
};

#if CSubFooVoid
void CSub::Foo(void)
{
DebugStr("\pCSub::Foo(void)");
}
#endif

void CBase::Foo(void)
{
DebugStr("\pCBase::Foo");
}

void CSub::Foo(int a)
{
#pragma unused(a)
DebugStr("\pCSub::Foo(int)");
}

void main(void)
{
CSub s;
CBase* pb = &s;
pb->Foo();
}
=============================================
--------------------
greg_m...@gdt.com
"Warning: Clean Up Desktop is not undoable."

Greg Manning

unread,
Dec 2, 1995, 3:00:00 AM12/2/95
to
In article <brians-0212...@slip-2-4.ots.utexas.edu>,
bri...@pbcomputing.com (Brian Stern) wrote:

>When the compiler is determining the scope of a particular name (like Foo
>in this case) it searches until it finds the scope that contains this name
>(CSub in this case). Then it tries to match the parameters. In your case
>it will fail.
>
>There is a new keyword 'using' that will solve this problem, when it
>appears. The usual solution is to have a function in the derived class
>that has the same signature as that of the inherited class and simply
>calls the inherited function. ...

OK, thanks for explaining that. I guess I don't really understand the
reason for this limitation of C++, unless it's to make writing compilers
easier, but I'll add the solution to my grab-bag of C++ work-arounds.

"A virtual function that has been defined in a base class need not be
defined in a derived class. If it is not, the function defined for the
base class is used in all calls." (well, evidently not)

Brian Stern

unread,
Dec 2, 1995, 3:00:00 AM12/2/95
to
In article <greg_manning-0...@host44.gdt.com>,
greg_m...@gdt.com (Greg Manning) wrote:

<In CW7, when "extended error checking" is on, the following program
<generates a warning.
<
<Warning : function declaration hides inherited virtual function
<CBaseAndSub.cp line 18 void Foo(int a);
<
<As far as I can tell, this warning is unmeritted. Now, I know that
<deciding when to generate warnings is a bit tricky since there are many
<perfectly legal C++ programs that contain dubious constructs. I would
<like to write code that avoids dubious constructs but I can't see what the
<dubious construct is that this warning is referring to. So, I'm inclined
<to think that this warning "should" not be generated...

You might fall off that incline.

Repeat after me: "I cannot overload and override at the same time"

When the compiler is determining the scope of a particular name (like Foo
in this case) it searches until it finds the scope that contains this name
(CSub in this case). Then it tries to match the parameters. In your case
it will fail.

There is a new keyword 'using' that will solve this problem, when it
appears. The usual solution is to have a function in the derived class
that has the same signature as that of the inherited class and simply

calls the inherited function. See below for the usual solution.

<=============================================
<#include "Types.h"
<
<// if this is defined to 1, no warning is generated
<#define CSubFooVoid 0
<
<class CBase
<{
<public:
< virtual void Foo(void);
<};
<
<class CSub : public CBase
<{
<public:
< #if CSubFooVoid
< void Foo(void);
< #endif
< void Foo(int a);
<};
<
<#if CSubFooVoid
< void CSub::Foo(void)
< {

// The usual solution is this:
CBase::Foo();

< DebugStr("\pCSub::Foo(void)");
< }
<#endif
<
<void CBase::Foo(void)
<{
< DebugStr("\pCBase::Foo");
<}
<
<void CSub::Foo(int a)
<{
< #pragma unused(a)
< DebugStr("\pCSub::Foo(int)");
<}
<
<void main(void)
<{
< CSub s;
< CBase* pb = &s;
< pb->Foo();
<}
<=============================================

<--------------------
<greg_m...@gdt.com
<"Warning: Clean Up Desktop is not undoable."

____________________________________________________________________
Brian Stern {8-{)} BeBox Hairy Guy St...@metrowerks.com Bri...@pbcomputing.com
INIT Writing FAQ etc. at <ftp://ftp.pbcomputing.com//Guests/BrianS/>

Chris Page

unread,
Dec 3, 1995, 3:00:00 AM12/3/95
to
In article <greg_manning-0...@host44.gdt.com>,
greg_m...@gdt.com says...
>>When the compiler is determining the scope of a particular name (like
Foo
>>in this case) it searches until it finds the scope that contains this
name
>>(CSub in this case). Then it tries to match the parameters. In your
case
>>it will fail.
>>
[snip]

>OK, thanks for explaining that. I guess I don't really understand the
>reason for this limitation of C++, unless it's to make writing compilers
[snip]


Why? Don't ask why. Imagine a situation where I've written a class
library which I distribute. Let's also pretend that the compiler does not
generate the message. You, being the savvy C++ programmer, decide to
extend one of my classes by adding CSub::foo(void), which hides my virtual
CBase::foo(void),
but for this example, let's pretend that CBase::foo(void) is NOT hidden by
CSub::foo(void). If this were the case, then you might define
CSub::foo(void), not knowing that CBase::foo(void) even exists.
CSub::foo(void) may do something completely different that
CBase::foo(void) so your program doesn't work, and you don't know why!
Designers decided it was better to generate the error and force you to
include

CSub::foo(void) { CBase::foo(); }

Hope this helps you understand why.

-Chris


Reply all
Reply to author
Forward
0 new messages