I am surprised that in the following example declaring Middle's base class private makes that name unavailable as a type in a subsequent derivation.
class Base {
public:
Base(Base const& b) : i(b.i) {}
int i;
};
class Middle : private Base { //<<<<<<<<<<<
public:
Middle(Base const* p) : Base(*p) {}
};
class Upper : public Middle {
public:
Upper(Base const* p) : Middle(p) {} //<<<<<<<<<<<
};
Compiling thusly with g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516...
g++ -std=c++11 privateBase.cpp
I get the following diagnostics:
privateBase.cpp:15:9: error: ‘class Base Base::Base’ is inaccessible within this context
Upper(Base const* p) : Middle(p) {}
^~~~
privateBase.cpp:1:12: note: declared here
class Base {
^
Clearly at the point that Base was used as Middle's base class its name was available as a type. I can understand that when Base is used to denote base class storage that should be private. But having a declaration of a private base class render a type name inaccessible seems, at the very least, unexpected.
Private members of the base class cannot be used by the derived class unless friend declarations within the base class explicitly grant access to them.
Derived class can not access the private members of it's base class. No type of inheritance allows access to private members. However if you use friend declaration you can do that. Save this answer.
This is intended; see core issue 175, which even added an example illustrating this in [class.access.spec]p5:
[ 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 ] [ 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 ]
This falls out of the interaction between class name injection (for rationale, see Why is there an injected class name?) and the fact that in C++ access control applies after name lookup, not before.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With