Why can't the C ++ compiler fix the problem between an inherited public and an inherited private method with the same name?

I am confused why the C ++ compiler will not accept this:

class Foo { private: void Baz() { } }; class Bar { public: void Baz() { }; class FooBar : public Foo, public Bar { }; void main() { FooBar fb; fb.Baz(); } 

The gcc error gives:

  request for member 'Baz' is ambiguous candidates are: void Bar::Baz() void Foo::Baz() 

but is it not obvious that I want Bar :: Baz (), since Foo :: Baz () is private? Why can't the compiler fix this problem?

+6
source share
5 answers

Name resolution works in two steps. First, the name is looked up, then the name is checked for access. If the search for a name is ambiguous, access is never considered.

As to why, perhaps this is a deliberate language design, but I think it would rather simplify the name resolution process. The rules are already diabolically complicated.

+7
source

This is not obvious - you could call a private member (if that was possible).

Formally, the rules of the language say that the name is first resolved and the best overload is selected. Only after that is there an availability check.

+3
source

To resolve this, you will need to consider whether you are in a context that allows you to call a private method or not. If allowed, then call:

 fb.Baz() 

may have completely different functionality depending on whether you call it from a public or private context. And this is not related to how the language works.

+2
source

Access restrictions do not affect inheritance. You always inherit everything from all base classes. In your case, this may seem unnecessary, but consider a slightly modified version where a private function is virtual:

 class Base { virtual void secret_power() { /* innocent default */ } public: void use_me() { secret_power(); } }; class Derived : public Base { virtual void secret_power() { /* overriding implementation here */ } }; 

Now for any Base& you can always call not use_me() public virtual interface, but your derived classes provide implementation using virtual virtual.

+1
source

As others have said, first the name is looked through, then access restrictions are applied. You can get around this by explicitly calling the method you want, as in

 fb.Bar::Baz() 
+1
source

Source: https://habr.com/ru/post/895995/


All Articles