In the following code snippet, I defined a nested class Inner
inside an encloding class Outer
. The inner class is placed inside a private section at the end of the enclosing class.
class Outer {
public:
Outer(): in(new Inner()) { // Case 1: OK
cout << "Outer ctor is called." << endl;
}
void f() {
Inner in2; // Case 2: OK
cout << "f() is called." << endl;
}
Inner *in1; // Case 3: error: 'Inner' does not name a type
void g(Inner in3) { // Case 4: error: 'Inner' does not name a type
cout << "g() is called." << endl;
}
int y = x + 2; // Case 5: OK to use a data member x defined in a later section
private:
class Inner {};
Inner *in;
int x = 1;
};
int main() {
Outer out;
out.f();
return 0;
}
Let's consider the following 5 cases:
- Case 1: use the
Inner
class in the constructor initializer list -- OK! - Case 2: use the
Inner
class as a type to define a local variable inside a member function -- OK! - Case 3: use the
Inner
class as a type to define a data member -- error: 'Inner' does not name a type - Case 4: use the
Inner
class as a method type -- error: 'Inner' does not name a type - Case 5: useage of a regular class data member is allowed before the definition of the data member in a different section.
I understand the errors I got are related to the declaration order: the Inner
class's declaration/definition appers after the public section that uses it. So if we switch the order of the private and public sections such that the Inner
class definition appears at the begining of the enclosing class, then all errors are gone. This is also pointed out by the answer to a similar question Can't use public nested class as private method parameter. But it is still unclear to me:
Why Case 1-2 work fine but Case 3-4 failed with error? what are the differences between Cases 1-2 and Cases 3-4? I know this is related to the declration order of the Inner class relative to the code that uses it. But why does the declaration order matter in some cases and not matter in other cases?
For Case 5 involving two regular class data members
x
andy
defined in two different sections (one public, one private), it is fine to use the data memberx
byy
even before x's definition. In more genral terms, no matter what the relative order of two (public/private) sections is, the code in one section may access the data members defined in the other section. But in the case of nested class member, we may run into errors if we use a nested class before its declaration section (such as in Case 3-4). So why do we have such a difference between a regular class member and a nested class member?