嵌套类

来自cppreference.com
< cpp‎ | language

class/structunion 的声明能出现在另一类内。这种声明声明一个嵌套类

[编辑] 解释

嵌套类的名称存在于外围类作用域,而且嵌套类成员函数的名称查找在检测嵌套类的作用域后观览外围类的作用域。同其外围域的任何成员,嵌套域拥有对所有外围类拥有访问的名称(私有、受保护等)的访问,但另外地它是独立的,而且对外围类的 this 指针无特定访问。

嵌套类的声明只能从外围类使用类型名、静态成员及枚举项。 (C++11 前)

嵌套类中的声明能使用外围类的所有成员,遵循非静态成员的通常使用规则

(C++11 起)
int x,y; // globals
class enclose { // 外围类
    int x; // 注意:私有成员
    static int s;
 public:
    struct inner { // 嵌套类
        void f(int i) {
            x = i; // 错误:不能不带实例地写入非静态的 enclose::x
            int a = sizeof x; // C++11 前错误。
                              // C++11 中 OK : sizeof 的运算数不求值,
                              // 非静态 enclose::x 的此使用是允许的。
            s = i;   // OK :能赋值给静态 enclose::s
            ::x = i; // OK :能赋值给全局 x
            y = i;   // OK :能赋值给全局 y
        }
        void g(enclose* p, int i) {
            p->x = i; // OK :赋值给 enclose::x
        }
    };
};

定义于嵌套类中的友元函数对外围类成员没有特定访问,即使来自定义于嵌套类中的成员函数体内的查找能找到外围类的私有成员。

嵌套类成员的类外定义出现在外围类的命名空间中:

struct enclose {
    struct inner {
        static int x;
        void f(int i);
    };
};
int enclose::inner::x = 1; // 定义
void enclose::inner::f(int i) {} // 定义

嵌套类可以前置声明并于稍后定义,在外围类的体内或体外:

class enclose {
    class nested1; // 前置声明
    class nested2; // 前置声明
    class nested1 {}; // 嵌套类的定义
};
class enclose::nested2 { }; // 嵌套类的定义

嵌套类声明服从成员访问指定符,私有成员类不能从外围类的作用域外指明,尽管可以操作该类的对象:

class enclose {
    struct nested { // 私有成员
        void g() {}
    };
 public:
    static nested f() { return nested{}; }
};
 
int main()
{
    //enclose::nested n1 = e.f(); // 错误: 'nested' 为私有
 
    enclose::f().g(); // OK :不指名 'nested'
    auto n2 = enclose::f(); // OK :不指名 'nested'
    n2.g();
}

[编辑] 引用

  • C++11 standard (ISO/IEC 14882:2011):
  • 9.7 Nested class declarations [class.nest]
  • C++98 standard (ISO/IEC 14882:1998):
  • 9.7 Nested class declarations [class.nest]