Base And Derived Class Access
Go Up to Member Scope Index
When you declare a derived class D, you list the base classes B1, B2, ... in a comma-delimited base-list:
class-key D : base-list { <member-list> }
D inherits all the members of these base classes. (Redefined base class members are inherited and can be accessed using scope overrides, if needed.) D can use only the public and protected members of its base classes. But, what will be the access attributes of the inherited members as viewed by D? D might want to use a public member from a base class, but make it private as far as outside functions are concerned. The solution is to use access specifiers in the base-list.
When declaring D, you can use the access specifier public, protected, or private in front of the classes in the base-list:
class D : public B1, private B2 /* , … */ {
// …
}
These modifiers do not alter the access attributes of base members as viewed by the base class, though they can alter the access attributes of base members as viewed by the derived class.
The default is private if D is a class declaration, and public if D is a struct declaration.
The derived class inherits access attributes from a base class as follows:
- public base class: public members of the base class are public members of the derived class. protected members of the base class are protected members of the derived class. private members of the base class remain private to the base class.
- protected base class: Both public and protected members of the base class are protected members of the derived class. private members of the base class remain private to the base class.
- private base class: Both public and protected members of the base class are private members of the derived class. private members of the base class remain private to the base class.
Note that private members of a base class are always inaccessible to member functions of the derived class unless friend declarations are explicitly declared in the base class granting access. For example,
/* class X is derived from class A */
class X : A { // default for class is private A
// …
}
/* class Y is derived (multiple inheritance) from B and C
B defaults to private B */
class Y : B, public C { // override default for C
// …
}
/* struct S is derived from D */
struct S : D { // default for struct is public D
// …
}
/* struct T is derived (multiple inheritance) from D and E
E defaults to public E */
struct T : private D, E { // override default for D
// E is public by default
// …
}
The effect of access specifiers in the base list can be adjusted by using a qualified-name in the public or protected declarations of the derived class. For example:
class B {
int a; // private by default
public:
int b, c;
int Bfunc(void);
};
class X : private B { // a, b, c, Bfunc are now private in X
int d; // private by default, NOTE: a is not
// accessible in X
public:
B::c; // c was private, now is public
int e;
int Xfunc(void);
};
int Efunc(X& x); // external to B and X
The function Efunc() can use only the public names c, e, and Xfunc().
The function Xfunc() is in X, which is derived from private B, so it has access to
- The "adjusted-to-public" c
- The "private-to-X" members from B: b and Bfunc()
- X's own private and public members: d, e, and Xfunc()
However, Xfunc() cannot access the "private-to-B" member, a.