Two kinds of access pertain to nested classes. First, where a nested class is declared controls the scope of the nested class; that is, it establishes which parts of a program can create objects of that class. Second, as with any class, the public, protected, and private sections of a nested class provide access control to class members. Where and how a nested class can be used depends on both scope and access control. Let’s examine these points further.
If a nested class is declared in a private section of a second class, it is known only to that second class. This applies, for example, to the Node
class nested in the Queue
declaration in the preceding example. Hence, Queue
members can use Node
objects and pointers to Node
objects, but other parts of a program don’t even know that the Node
class exists. If you were to derive a class from Queue
, Node
would be invisible to that class, too, because a derived class can’t directly access the private parts of a base class.
If the nested class is declared in a protected section of a second class, it is visible to that class but invisible to the outside world. However, in this case, a derived class would know about the nested class and could directly create objects of that type.
If a nested class is declared in a public section of a second class, it is available to the second class, to classes derived from the second class, and, because it’s public, to the outside world. However, because the nested class has class scope, it has to be used with a class qualifier in the outside world. For example, suppose you have this declaration:
class Team
{
public:
class Coach { ... };
...
};
Now suppose you have an unemployed coach, one who belongs to no team. To create a Coach
object outside the Team
class, you can use this:
Team::Coach forhire; // create a Coach object outside the Team class
These same scope considerations apply to nested structures and enumerations, too. Indeed, many programmers use public enumerations to provide class constants that can be used by client programmers. For example, the many implementations of classes defined to support the iostream
facility use this technique to provide various formatting options, as you’ve already seen (and will explore more fully in Chapter 17, “Input, Output, and Files”). Table 15.1 summarizes scope properties for nested classes, structures, and enumerations.
After a class is in scope, access control comes into play. The same rules govern access to a nested class that govern access to a regular class. Declaring the Node
class in the Queue
class declaration does not grant the Queue
class any special access privileges to the Node
class, nor does it grant the Node
class any special access privileges to the Queue
class. Thus, a Queue
class object can access only the public members of a Node
object explicitly. For that reason, the Queue
example makes all the members of the Node
class public. This violates the usual practice of making data members private, but the Node
class is an internal implementation feature of the Queue
class and is not visible to the outside world. That’s because the Node
class is declared in the private section of the Queue
class. Thus, although Queue
methods can access Node
members directly, a client using the Queue
class cannot do so.
In short, the location of a class declaration determines the scope or visibility of a class. Given that a particular class is in scope, the usual access control rules (public, protected, private, friend) determine the access a program has to members of the nested class.
3.14.141.115