C++ 嵌套类/结构
示例
甲class或struct还可以包含另一个class/struct内部本身的定义,这被称为“嵌套类”;在这种情况下,包含类称为“封闭类”。嵌套类定义被认为是封闭类的成员,但在其他方面则是单独的。
struct Outer {
struct Inner { };
};从封闭类的外部,可以使用范围运算符访问嵌套类。但是,在封闭类的内部,可以使用没有限定符的嵌套类:
struct Outer {
struct Inner { };
Inner in;
};
//...
Outer o;
Outer::Inner i = o.in;与非嵌套class/一样struct,成员函数和静态变量可以在嵌套类内或在封闭的名称空间中定义。但是,由于它们被认为是与嵌套类不同的类,因此无法在封闭类中定义它们。
//坏。
struct Outer {
struct Inner {
void do_something();
};
void Inner::do_something() {}
};
//好。
struct Outer {
struct Inner {
void do_something();
};
};
void Outer::Inner::do_something() {}与非嵌套类一样,嵌套类可以在以后直接声明和定义,前提是在直接使用之前对其进行了定义。
class Outer {
class Inner1;
class Inner2;
class Inner1 {};
Inner1 in1;
Inner2* in2p;
public:
Outer();
~Outer();
};
class Outer::Inner2 {};
Outer::Outer() : in1(Inner1()), in2p(new Inner2) {}
Outer::~Outer() {
if (in2p) { delete in2p; }
}在C++11之前,嵌套类只能static从封闭的类中访问类型名称,成员和枚举数。封闭类中定义的所有其他成员是禁止进入的。
从C++11开始,嵌套类及其成员被视为friend封闭类的成员,并且可以根据通常的访问规则来访问其所有成员。如果嵌套类的成员需要能够评估封闭类的一个或多个非静态成员,则必须为它们传递一个实例:
class Outer {
struct Inner {
int get_sizeof_x() {
return sizeof(x); //合法(C++11):x未评估,因此不需要实例。
}
int get_x() {
return x; //非法:没有实例就无法访问非静态成员。
}
int get_x(Outer& o) {
return o.x; //合法(C++11):作为Outer的成员,Inner可以访问私有成员。
}
};
int x;
};相反,封闭类不会被视为嵌套类的朋友,因此,如果未明确授予其权限,则无法访问其私有成员。
class Outer {
class Inner {
//朋友班外
int x;
};
Inner in;
public:
int get_x() {
return in.x; //错误:intOuter::Inner::x是私有的。
// Uncomment "friend" line above to fix.
}
};嵌套类的朋友不会自动视为封闭类的朋友;如果他们也需要成为封闭类的朋友,则必须分别声明。相反,由于封闭类不会自动被视为嵌套类的朋友,因此封闭类的朋友也不会被视为嵌套类的朋友。
class Outer {
friend void barge_out(Outer& out, Inner& in);
class Inner {
friend void barge_in(Outer& out, Inner& in);
int i;
};
int o;
};
void barge_in(Outer& out, Outer::Inner& in) {
int i = in.i; //好。
int o = out.o; //错误:intOuter::o是私有的。
}
void barge_out(Outer& out, Outer::Inner& in) {
int i = in.i; //错误:intOuter::Inner::i是私有的。
int o = out.o; //好。
}