Board index » cppbuilder » Method overloading in descendant class

Method overloading in descendant class


2006-11-14 07:49:18 PM
cppbuilder97
Hi,
I derived TMainMenu and overloaded the FindItem method:
class TMyMainMenu : public TMainMenu
{
public:
int __fastcall FindItem(const AnsiString &ItemName);
}
It turns out that my new method shadowed its ancestor method, namely
TMenu::FindItem, even though they have different signatures.
The only wokaround I found is to typecast TMyMainMenu to TMainMenu.
Is that correct C++ behavior?
 
 

Re:Method overloading in descendant class

"Iaacov" < XXXX@XXXXX.COM >wrote:
Quote
Hi,

I derived TMainMenu and overloaded the FindItem method:

class TMyMainMenu : public TMainMenu
{
public:
int __fastcall FindItem(const AnsiString &ItemName);
}

It turns out that my new method shadowed its ancestor method, namely
TMenu::FindItem, even though they have different signatures.

The only wokaround I found is to typecast TMyMainMenu to TMainMenu.

Is that correct C++ behavior?
The correct C++ behaviour is for a method in a derived class to hide (is
this what you meant by 'shadowing'?) all methods with the same NAME (not
just the same signature) in its base class(es). This is because of how
function lookup proceeds.
Roughly speaking, it works as follows:
If a function f is being called on an object of class C, then:
a) Look for f in the definition of C
b) If not found there, look for it in the parent of C
c) If not found there, look for it in the parent of the parent of C
...
So, the problem with declaring a new FindItem in the derived class is
that the lookup process stops early.
The solution is quite simple - use a using directive:
class TMyMainMenu : public TMainMenu
{
public:
using TMainMenu::FindItem;
int __fastcall FindItem(const AnsiString &ItemName);
};
which tells the compiler that the base class members are to be
considered as if declared here.
Alan Bellingham
--
ACCU Conference: 11-14 April 2007 - Paramount Oxford Hotel
 

Re:Method overloading in descendant class

Hi Alan,
Your explanation was very instructive.
Quote
The solution is quite simple - use a using directive:
To be exact, you mean a using declaration. Directives are used to access
namespaces.
Thanks a lot.
 

{smallsort}

Re:Method overloading in descendant class

"Iaacov" < XXXX@XXXXX.COM >wrote:
Quote
To be exact, you mean a using declaration. Directives are used to access
namespaces.
Damn, can never remember which is which off the top of my head.
Glad to have helped.
Alan Bellingham
--
ACCU Conference: 11-14 April 2007 - Paramount Oxford Hotel
 

Re:Method overloading in descendant class

"Iaacov" < XXXX@XXXXX.COM >writes:
Quote
Hi,

I derived TMainMenu and overloaded the FindItem method:

class TMyMainMenu : public TMainMenu
{
public:
int __fastcall FindItem(const AnsiString &ItemName);
}

It turns out that my new method shadowed its ancestor method, namely
TMenu::FindItem, even though they have different signatures.

The only wokaround I found is to typecast TMyMainMenu to TMainMenu.

Is that correct C++ behavior?
Yes. Name lookup rules are tricky, but in essence, C++ builds a set
of possible functions BEFORE it starts to do overload resolution.
Once it finds the name in a scope, it stops looking in other scopes
for more functions with the same name.
Therefore, your derived function prevents the compiler from looking in
the base class, since once it's found, it stops searching. When it
performs overload resolution, it only considers the names found in the
scope of your derived class, since that's where the first name was
found.
You can pull the base implementation into the derived class's scope
by placing this in your derived class:
using TMainMenu::FindItem;
Now the lookup rules will find both FindItem functions in the derived
scope, and then will choose which one to call based on the overload
resolution.
--
Chris (TeamB);