question

IgnorantiaLegis-1415 avatar image
0 Votes"
IgnorantiaLegis-1415 asked ·

Standard C++ polymorphic virtual function at different levels of class hierarchy

Using MS Visual Studio Community 2019, 16.9.0

First step. Excerpt from the project, no polymorphism, works fine:

 class MyWindow {
 protected:
 virtual void ProcessChar(char chChar, int iRepeat) { /* ...does not matter... */ }
 }
    
 class MyDialogControl : public MyWindow {
 /* ...no need to define ProcessChar here, it's inherited... */
 }
    
 class MySignedEditControl : public MyDialogControl {
 typedef MyDialogControl super;
 protected:
 virtual void ProcessChar(char chChar, int iRepeat) {
 /* ...some individual stuff here .../
 super::ProcessChar(chChar, iRepeat); }
 }

As expected, super::ProcessChar calls MyWindow::ProcessChar.
Second step. Add a polymorphic function to MyDialogControl. Some other classes derived from MyDialogControl will need it later.

 class MyDialogControl : public MyWindow {
 protected:
 /* ...ProcessChar(char chChar, int iRepeat) should still be inherited... */
 virtual bool ProcessChar(NMCHAR*) { /* do some stuff here */ }
 }

Unexpected result: compile error in class MySignedEditControl , type mismatch at line: super::ProcessChar(chChar, iRepeat) does not match with ProcessChar(NMCHAR*).

There are - at least - 3 obvious solutions. Polymorphism is not essential here, so by just renaming the new function to "ProcessCharNotification(NMCHAR*)" everything turns out fine. 2nd: in MySignedEditControl calling "Window::ProcessChar" instead of "super::ProcessChar" will allow me to keep the polymorphic function name. 3rd: Defining a redirect "MyDialogControl::ProcessChar" which does nothing than call its own "super::ProcessChar" works fine.

So my question ist not about how to find a solution. I just want to understand the mechanism - why does the polymorphic call not compile in the above example? What does the C++ standard say in this case?

Thanks in advance.




vs-generalc++
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

IgorTandetnik-1300 avatar image
0 Votes"
IgorTandetnik-1300 answered ·

Add using MyWindow::ProcessChar; to MyDialogControl.

Introducing a member with a given name hides members with the same name inherited from base class. Name lookup searches the scopes from the inside out, and stops as soon as it finds a matching name; further scopes are not searched. If more than one function is thus found, overload resolution is performed next.

When you added ProcessChar to MyDialogControl, the name lookup for super::ProcessChar finds that declaration and doesn't look further, and so doesn't find MyWindow::ProcessChar. using declaration brings names from MyWindow down to MyDialogControl, and allows name lookup to find them.

· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Using! Very good.

Thank you for your comprehensive explanation.

0 Votes 0 ·