名稱空間
變體
操作

巢狀類

來自 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++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
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]