命名空间
变体
操作

嵌套类

来自 cppreference.cn
< cpp‎ | language
 
 
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++ 标准。

DR 应用于 已发布行为 正确行为
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]