1

Why does an interface have a special visibility in a method due to a private inheritance?

Note that a global specifier :: is required in my derived class.

I don't understand why a method inherits some kind of visibility due to private inheritance. It's totally reasonable that Derived class doesn't have access to Control. But why doesn't it have access through a member either?

class Control { public: void ModifySomething(); }; class Base : private Control { private: virtual void Update( Control& i_control ); }; class Derived : public Base { private: // ----------↓↓ void Update( ::Control& i_control ) override; }; 

Note: I understand we could fix this by composition. But I would like to know why it's defined like that in C++. Could we break const-ness or something?

4
  • 3
    You seem to be asking multiple different questions. Can you edit your question so that it asks a single clear question? Commented Oct 14, 2019 at 15:48
  • 1
    what you mean by But why also through a member? Commented Oct 14, 2019 at 15:55
  • @Brian is it fine now? Commented Oct 14, 2019 at 17:17
  • @appleapple Fixed readability Commented Oct 14, 2019 at 17:17

2 Answers 2

3

class Derived doesn't have access to anything private in class Base, so it doesn't have access to class Control through Base. It can, however, access Control directly because it's declared in the same global scope as Derived.

As @formerlyknownas_463035818 comments, there are two paths to Control from Derived but one is blocked due to private access control so the other, global path, is chosen.

Sign up to request clarification or add additional context in comments.

3 Comments

would be correct to say that Control is in scope via two different paths and the one that has to be prefered by the compiler is blocked, because it is private?
I don't understand why these two paths exist. Why is it defined like that in the language? private inheritance should be like it doesn't exist to the derived class. However, it does exist because I need to specify the global scope.
Because Control is in the global namespace, privately inheriting it doesn't change that.
1

According to the C++ 17 Standard (14.1 Access specifiers)

5 [ Note: In a derived class, the lookup of a base class name will find the injected-class-name instead of the name of the base class in the scope in which it was declared. The injected-class-name might be less accessible than the name of the base class in the scope in which it was declared. — end note ]

And there is an example similar to your code snippet.

[Example:

class A { }; class B : private A { }; class C : public B { A* p; // error: injected-class-name A is inaccessible ::A* q; // OK }; 

— end example ]

That is the injected class name of the private base class within the derived class definition hides the name of the base class defined in the namespace. And this injected name is private. So the derived class does not have an access to this private injected name.

1 Comment

That is the concept and explanation I was looking for: injected-class-name

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.