Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: XE8 enterprice, bcc32 : warning 8022 - virtual function x hides y



Permlink Replies: 1 - Last Post: Jan 19, 2017 12:11 PM Last Post By: Remy Lebeau (Te... Threads: [ Previous | Next ]
Jan Dijkstra

Posts: 206
Registered: 11/4/99
XE8 enterprice, bcc32 : warning 8022 - virtual function x hides y
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 19, 2017 2:30 AM
I have the following setup in a parent class (showing only relevant excerpt)
class TBfwParentedCoreIdProvider
{
public:
               __fastcall  TBfwParentedCoreIdProvider (TComponent *owner);
  virtual      __fastcall ~TBfwParentedCoreIdProvider (void);
 
  virtual TLicListItem * __fastcall Create (TLicListItem *keyToMatch, TStorageCreateMode mode);
  virtual TLicListItem * __fastcall Create (TLicListItem *keyToMatch);
  virtual TLicListItem * __fastcall Create (void);
};

I make a derived class like so
class TBfwBendlistCoreIdProvider : public  TBfwParentedCoreIdProvider
{
public:
               __fastcall  TBfwBendlistCoreIdProvider (TComponent *owner);
  virtual      __fastcall ~TBfwBendlistCoreIdProvider (void);
 
  virtual TLicListItem * __fastcall Create (void);
 
  using TBfwParentedCoreIdProvider::Create;
};

When I compile this, I get warning 8022, two times, that Create () hides TBfwParentedCoreIdProvider::Create (). Each one is for one of the virtuals that I did not re-implement.

When I use this like x->Create (someKeyToMatch), where x is of the TBfwBendlistCoreIdProvider * type, it works like I expect it to work (TBfwParentedCoreIdProvider::Create (key) gets called). So why does the compiler issue the warning. Isn't the using clause supposed to remove this warning?
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: XE8 enterprice, bcc32 : warning 8022 - virtual function x hides y
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 19, 2017 12:11 PM   in response to: Jan Dijkstra in response to: Jan Dijkstra
Jan wrote:

virtual TLicListItem * __fastcall Create (TLicListItem *keyToMatch, TStorageCreateMode
mode);
virtual TLicListItem * __fastcall Create (TLicListItem *keyToMatch);
virtual TLicListItem * __fastcall Create (void);

I would suggest defining a single method with optional parameters instead,
eg:

virtual TLicListItem * __fastcall Create (TLicListItem *keyToMatch = NULL, 
TStorageCreateMode mode = /*whatever default value to want*/);


Then there is only one method for descendants to override, and you don't
need to have a 'using' statement anymore (which you don't need anyway, see
my comment further below).

When I compile this, I get warning 8022, two times, that Create ()
hides TBfwParentedCoreIdProvider::Create ().

Because it really does hide them. See:

http://en.cppreference.com/w/cpp/language/using_declaration

In class definition

Using-declaration introduces a member of a base class into the derived class
definition, such as to **expose a protected member** of base as public member
of derived. In this case, nested-name-specifier must name a base class of
the one being defined. If the name is the name of an overloaded member function
of the base class, all base class member functions with that name are introduced.
**If the derived class already has a member with the same name, parameter
list, and qualifications, the derived class member hides or overrides (doesn't
conflict with) the member that is introduced from the base class.**

The 'using' statement brings in all of the overloaded methods, bu then you
are overriding only one of them, causing the others to be hidden. You would
have to override all three (in which case, the 'using' statement becomes
redundant, even those it already is to begin with, see the next comment below).

Note that your methods are 'public' to begin with, and you are using 'public'
inheritance, so there is no need for any 'using' statement at all, as they
are already inherited and publically accessible in descendants. Only if
the methods were declared as 'protected', or you were using 'protected' inheritance,
then a 'using' statement would make sense.

When I use this like x->Create (someKeyToMatch), where x is of the
TBfwBendlistCoreIdProvider * type, it works like I expect it to work
(TBfwParentedCoreIdProvider::Create (key) gets called).

It would work the same even without the 'using' statement being present.

So why does the compiler issue the warning.

Because it is supposed to.

Isn't the using clause supposed to remove this warning?

No.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02