public
, private
, and protected
InheritanceAccess to a member that a class inherits is controlled by a combination of the access specifier for that member in the base class, and the access specifier in the derivation list of the derived class. As an example, consider the following hierarchy:
class Base {
public:
void pub_mem(); // public member
protected:
int prot_mem; // protected member
private:
char priv_mem; // private member
};
struct Pub_Derv : public Base {
// ok: derived classes can access protected members
int f() { return prot_mem; }
// error: private members are inaccessible to derived classes
char g() { return priv_mem; }
};
struct Priv_Derv : private Base {
// private derivation doesn't affect access in the derived class
int f1() const { return prot_mem; }
};
The derivation access specifier has no effect on whether members (and friends) of a derived class may access the members of its own direct base class. Access to the members of a base class is controlled by the access specifiers in the base class itself. Both Pub_Derv
and Priv_Derv
may access the protected
member prot_mem
. Neither may access the private
member priv_mem
.
The purpose of the derivation access specifier is to control the access that users of the derived class—including other classes derived from the derived class—have to the members inherited from Base
:
Pub_Derv d1; // members inherited from Base are public
Priv_Derv d2; // members inherited from Base are private
d1.pub_mem(); // ok: pub_mem is public in the derived class
d2.pub_mem(); // error: pub_mem is private in the derived class
Both Pub_Derv
and Priv_Derv
inherit the pub_mem
function. When the inheritance is public
, members retain their access specification. Thus, d1
can call pub_mem
. In Priv_Derv
, the members of Base
are private
; users of that class may not call pub_mem
.
The derivation access specifier used by a derived class also controls access from classes that inherit from that derived class:
struct Derived_from_Public : public Pub_Derv {
// ok: Base::prot_mem remains protected in Pub_Derv
int use_base() { return prot_mem; }
};
struct Derived_from_Private : public Priv_Derv {
// error: Base::prot_mem is private in Priv_Derv
int use_base() { return prot_mem; }
};
Classes derived from Pub_Derv
may access prot_mem
from Base
because that member remains a protected
member in Pub_Derv
. In contrast, classes derived from Priv_Derv
have no such access. To them, all the members that Priv_Derv
inherited from Base
are private
.
Had we defined another class, say, Prot_Derv
, that used protected
inheritance, the public
members of Base
would be protected
members in that class. Users of Prot_Derv
would have no access to pub_mem
, but the members and friends of Prot_Derv
could access that inherited member.