Nested Classes
Classes can be defined inside other classes. Classes that are defined inside other classes are called nested classes. Nested classes are used in situations where the nested class has a close conceptual relationship to its surrounding class. For example, with the class string
a type string::iterator
is available which will provide all characters that are stored in the string
. This string::iterator
type could be defined as an object iterator
, defined as nested class in the class string
.
A class can be nested in every part of the surrounding class: in the public, protected
or private
section. Such a nested class can be considered a member of the surrounding class. The normal access and rules in classes apply to nested classes. If a class is nested in the public
section of a class, it is visible outside the surrounding class. If it is nested in the protected
section it is visible in subclasses, derived from the surrounding class , if it is nested in the private
section, it is only visible for the members of the surrounding class.
The surrounding class has no special privileges with respect to the nested class. So, the nested class still has full control over the accessibility of its members by the surrounding class. For example, consider the following class definition:
class SurroundIn this definition access to the members is defined as follows:
{
public:
class FirstWithin
{
int d_variable;
public:
FirstWithin();
int var() const;
};
private:
class SecondWithin
{
int d_variable;
public:
SecondWithin();
int var() const;
};
};
inline int Surround::FirstWithin::var() const
{
return d_variable;
}
inline int Surround::SecondWithin::var() const
{
return d_variable;
}
- The class
FirstWithin
is visible both outside and insideSurround
. The classFirstWithin
therefore has global scope. - The constructor
FirstWithin()
and the member functionvar()
of the classFirstWithin
are also globally visible. - The
int d_variable
datamember is only visible to the members of the classFirstWithin
. Neither the members ofSurround
nor the members ofSecondWithin
can accessd_variable
of the classFirstWithin
directly. - The class
SecondWithin
is only visible insideSurround
. The public members of the classSecondWithin
can also be used by the members of the classFirstWithin
, as nested classes can be considered members of their surrounding class. - The constructor
SecondWithin()
and the member functionvar()
of the classSecondWithin
can also only be reached by the members ofSurround
(and by the members of its nested classes). - The
int d_variable
datamember of the classSecondWithin
is only visible to the members of the classSecondWithin
. Neither the members ofSurround
nor the members ofFirstWithin
can accessd_variable
of the classSecondWithin
directly. - As always, an object of the class type is required before its members can be called. This also holds true for nested classes.
friend
classes. The nested classes can be considered members of the surrounding class, but the members of nested classes are not members of the surrounding class. So, a member of the class Surround
may not access FirstWithin::var()
directly. This is understandable considering the fact that a Surround
object is not also a FirstWithin
or SecondWithin
object. In fact, nested classes are just typenames. It is not implied that objects of such classes automatically exist in the surrounding class. If a member of the surrounding class should use a (non-static) member of a nested class then the surrounding class must define a nested class object, which can thereupon be used by the members of the surrounding class to use members of the nested class.
For example, in the following class definition there is a surrounding class Outer
and a nested class Inner
. The class Outer
contains a member function caller()
which uses the inner
object that is composed in Outer
to call the infunction()
member function of Inner
:
class OuterThe mentioned function
{
public:
void caller();
private:
class Inner
{
public:
void infunction();
};
Inner d_inner; // class Inner must be known
};
void Outer::caller()
{
d_inner.infunction();
}
Inner::infunction()
can be called as part of the inline definition of Outer::caller()
, even though the definition of the class Inner
is yet to be seen by the compiler. On the other hand, the compiler must have seen the definition of the class Inner
before a data member of that class can be defined.
0 comments:
Post a Comment