命名空间
变体
操作

嵌套类

来自 cppreference.cn
< cpp‎ | 语言
 
 
C++ 语言
 
 

类/结构体联合体 的声明可以出现在另一个类中。这样的声明声明了一个嵌套类

[编辑] 解释

嵌套类的名称存在于外围类的作用域中,并且从嵌套类的成员函数进行名称查找时,在检查嵌套类的作用域后会访问外围类的作用域。像其外围类的任何成员一样,嵌套类可以访问外围类有权访问的所有名称(私有、保护等),但它在其他方面是独立的,并且对外围类的 this 指针没有特殊访问权限。嵌套类中的声明可以使用外围类的任何成员,遵循非静态成员的常规使用规则

int x, y; // globals
class enclose // enclosing class
{
    // note: private members
    int x;
    static int s;
public:
    struct inner // nested class
    {
        void f(int i)
        {
            x = i; // Error: can't write to non-static enclose::x without instance
            int a = sizeof x; // Error until C++11,
                              // OK in C++11: operand of sizeof is unevaluated,
                              // this use of the non-static enclose::x is allowed.
            s = i;   // OK: can assign to the static enclose::s
            ::x = i; // OK: can assign to global x
            y = i;   // OK: can assign to global y
        }
 
        void g(enclose* p, int i)
        {
            p->x = i; // OK: assign to enclose::x
        }
    };
};

即使从嵌套类中定义的成员函数的主体进行查找可以找到外围类的私有成员,在嵌套类中定义的友元函数也对外围类的成员没有特殊访问权限。

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

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

嵌套类可以前向声明并随后定义,无论是在同一个外围类主体内还是在其外部

class enclose
{
    class nested1;    // forward declaration
    class nested2;    // forward declaration
    class nested1 {}; // definition of nested class
};
 
class enclose::nested2 {}; // definition of nested class

嵌套类声明遵循成员访问说明符,私有成员类不能在外围类的作用域之外命名,尽管该类的对象可以被操作

class enclose
{
    struct nested // private member
    {
        void g() {}
    };
public:
    static nested f() { return nested{}; }
};
 
int main()
{
    //enclose::nested n1 = enclose::f(); // error: 'nested' is private
 
    enclose::f().g();       // OK: does not name 'nested'
    auto n2 = enclose::f(); // OK: does not name 'nested'
    n2.g();
}

[编辑] 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 发布时的行为 正确的行为
CWG 45 C++98 嵌套类的成员不能
访问外围类及其友元
它们拥有与
外围类的其他成员相同的访问权限
(也解决了 CWG 问题 #8 和 #10)

[编辑] 参考

  • C++23 标准 (ISO/IEC 14882:2024)
  • 11.4.12 嵌套类声明 [class.nest]
  • C++20 标准 (ISO/IEC 14882:2020)
  • 11.4.10 嵌套类声明 [class.nest]
  • C++17 标准 (ISO/IEC 14882:2017)
  • 12.2.5 嵌套类声明 [class.nest]
  • C++14 标准 (ISO/IEC 14882:2014)
  • 9.7 嵌套类声明 [class.nest]
  • C++11 标准 (ISO/IEC 14882:2011)
  • 9.7 嵌套类声明 [class.nest]
  • C++98 标准 (ISO/IEC 14882:1998)
  • 9.7 嵌套类声明 [class.nest]