命名空间
变体
操作

嵌套类

来自 cppreference.com
< 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++ 标准。

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]