A class can be defined inside a function body. Such a class is called a local class. A local class defines a type that is visible only in the scope in which it is defined. Unlike nested classes, the members of a local class are severely restricted.
All members, including functions, of a local class must be completely defined inside the class body. As a result, local classes are much less useful than nested classes.
In practice, the requirement that members be fully defined within the class limits the complexity of the member functions of a local class. Functions in local classes are rarely more than a few lines of code. Beyond that, the code becomes difficult for the reader to understand.
Similarly, a local class is not permitted to declare static
data members, there being no way to define them.
The names from the enclosing scope that a local class can access are limited. A local class can access only type names, static
variables (§ 6.1.1, p. 205), and enumerators defined within the enclosing local scopes. A local class may not use the ordinary local variables of the function in which the class is defined:
int a, val;
void foo(int val)
{
static int si;
enum Loc { a = 1024, b };
// Bar is local to foo
struct Bar {
Loc locVal; // ok: uses a local type name
int barVal;
void fooBar(Loc l = a) // ok: default argument is Loc::a
{
barVal = val; // error: val is local to foo
barVal = ::val; // ok: uses a global object
barVal = si; // ok: uses a static local object
locVal = b; // ok: uses an enumerator
}
};
// . . .
}
The enclosing function has no special access privileges to the private
members of the local class. Of course, the local class could make the enclosing function a friend. More typically, a local class defines its members as public
. The portion of a program that can access a local class is very limited. A local class is already encapsulated within the scope of the function. Further encapsulation through information hiding is often overkill.
Name lookup within the body of a local class happens in the same manner as for other classes. Names used in the declarations of the members of the class must be in scope before the use of the name. Names used in the definition of a member can appear anywhere in the class. If a name is not found as a class member, then the search continues in the enclosing scope and then out to the scope enclosing the function itself.
It is possible to nest a class inside a local class. In this case, the nested class definition can appear outside the local-class body. However, the nested class must be defined in the same scope as that in which the local class is defined.
void foo()
{
class Bar {
public:
// ...
class Nested; // declares class Nested
};
// definition of Nested
class Bar::Nested {
// ...
};
}
As usual, when we define a member outside a class, we must indicate the scope of the name. Hence, we defined Bar::Nested
, which says that Nested
is a class defined in the scope of Bar
.
A class nested in a local class is itself a local class, with all the attendant restrictions. All members of the nested class must be defined inside the body of the nested class itself.