CPSC 427: Object-Oriented Programming
Michael J. Fischer
Name Visibility
Private
derivation
(default)
class B : A { ... }; specifies private derivation of B from
A.
A class member inherited from A become private in B.
Like other private members, it is inaccessible outside of B.
If public in A, it can be accessed from within A or B or via an instance
of A, but not via an instance of B.
If private in A, it can only be accessed from within A.
It cannot even be accessed from within B.
Private derivation example Example:
Public
derivation
class B : public A { ... }; specifies public derivation of B from
A.
A class member inherited from A retains its privacy status from
A.
If public in A, it can be accessed from within B and also via instances
of A or B.
If private in A, it can only be accessed from within A.
It cannot even be accessed from within B.
Public derivation example
Example:
The protected keyword
protected is a privacy status between public and private.
Protected class members are inaccessible from outside the class (like
private) but accessible within a derived class (like public).
Example:
Protected derivation
class B : protected A { ... }; specifies protected derivation of B
from A.
A public or protected class member inherited from A becomes
protected in B.
If public in A, it can be accessed from within B and also via instances
of A but not via instances of B.
If protected in A, it can be accessed from within A or B but not from
outside.
If private in A, it can only be accessed from within A.
It cannot be accessed from within B.
Surprising
example
1
1 class A {
2 protected:
3 int x;
4 };
5 class B : public A {
6 public:
7 int f() { return x; } // ok
8 int g(A* a) { return a->x; } // privacy violation
9 };
Result:
Surprising
example
2:
contrast
the
following
1 class A { };
2 class B : public A {}; // <-- public derivation
3 int main() { A* ap; B* bp;
4 ap = bp; }
Result: OK.
___________________________________________________________
1 class A { };
2 class B : private A {}; // <-- private derivation
3 int main() { A* ap; B* bp;
4 ap = bp; }
Result:
Surprising
example
3
1 class A { protected: int x; };
2 class B : protected A {};
3 int main() { A* ap; B* bp;
4 ap = bp; }
Result:
Names, Members, and Contexts
Data and function names can be declared in many different contexts in
C++: in a class, globally, in function parameter lists, and in code blocks
(viz. local variables).
Often the same identifier will be declared multiple times in different
contexts.
Two steps to determining the meaning of an occurrence of an identifier:
Declaration and reference contexts
Every reference x to a class data or function member has two contexts associated with it:
Accessibility rules apply to class data and function members depend on both the declaration context and the reference context of a reference x.
Declaration context example
Example:
Reference context example
All three commented occurrences of x have declaration context A because all three refer to A::x, the data member declared in class A.
Inside and outside class references
A reference x to a data/function member of class A is
For simple classes:
Examples
References to A::x
Inherited names
In a derived class, names from the base class are inherited by the derived
class, but their privacy settings are altered as described in the last
lecture.
The result is that the same member exists in both classes but with
possibly different privacy settings.
Question: Which privacy setting is used to determine visibility?
Answer: The one of the declaration context of the referent.
Inheritance example
Let bb be an instance of class B. Then bb contains a field x, inherited from class A. This field has two names A::x and B::x.
The names are distinct and may have different privacy attributes. In this example, A::x is protected and B::x is private.
First reference is okay since the declaration context of x is B.
Second reference is not since the declaration context of x is A.
Both occurrences have reference context B.
Inaccessible base class
A base class pointer can only reference an object of a derived class if
doing so would not violate the derived class’s privacy. Recall surprising
example 2 (bottom):
1 class A { };
2 class B : private A {}; // <-- private derivation
3 int main() { A* ap; B* bp;
4 ap = bp; }
The idea is that with private derivation, the fact that B is derived from A
should be completely invisible from the outside.
With protected derivation, it should be completely invisible except to its descendants.
Visibility rules
Every class member has one of four privacy attributes: public,
protected, private, or hidden.
These attributes determine the locations from which a class member can be seen.
Explicit privacy attributes
The privacy attributes for declared class members are given explicitly by
the privacy keywords public, protected, and private.
There is no way to explicitly declare a hidden member.
Example:
Implicit privacy attributes
Inherited class members are assigned implicit privacy attributes based on their attributes in the parent class and by the kind of derivation, whether public, protected, or private.
Implicit privacy chart
Below is a revision of the chart presented in lecture 10.
Attribute
in base
class

| Kind of Derivation | |||
| public | protected | private | |
| public | public | protected | private |
| protected | protected | protected | private |
| private | hidden | hidden | hidden |
| hidden | hidden | hidden | hidden |
| Attribute in derived class. | |||
Summary
Demo: Craps Game
Game Rules The player (known as the shooter) rolls a pair of fair dice
(From http://www.math.uah.edu/stat/games/Craps.html)
A Craps simulator
Demo 17-Craps illustrates the use of derived classes in order to allow the simulator to work with both random dice and “prerecorded” dice throws stored in a file.