C++嵌套類

來源:互聯網
上載者:User

標籤:ons   head   成員   complete   template   ror   ref   ati   use   

可以在另一個類內部定義一個類,這樣的類是嵌套類,也稱為巢狀型別。嵌套類是獨立的類,基本上與它們的外圍類不相關,外圍類對嵌套類的成員沒有特殊訪問權,並且嵌套類對其外圍類的成員也沒有特殊訪問權。

嵌套類的名字在其外圍類的範圍中可見,但在其他類範圍或定義外圍類的範圍中不可見。嵌套類的名字將不會與另一範圍中聲明的名字衝突。

嵌套類定義了其外圍類中的一個類型成員。像任何其他成員一樣,外圍類決定對這個類型的訪問。在外圍類的 public 部分定義的嵌套類定義了可在任何地方使用的類型,在外圍類的 protected 部分定義的嵌套類定義了只能由外圍類、友元或衍生類別訪問的類型,在外圍類的 private 部分定義的嵌套類定義了只能被外圍類或其友元訪問的類型。

 

1:例子

template <class Type> class Queue {public:    ... private:    // public members are ok: QueueItem is a private member of Queue    // only Queue and its friends may access the members of QueueItem    struct QueueItem {        QueueItem(const Type &);        Type item;         QueueItem *next;     };    QueueItem *head;     QueueItem *tail;};

因為 QueueItem 類是 private 成員,所以只有 Queue 類的成員和友元可以使用 QueueItem 類型。使 QueueItem 類成為 private 成員之後,就可以使QueueItem 成員 public。

 

因為 Queue 類是一個模板,它的成員也隱含地是模板。具體而言,嵌套類QueueItem 隱含地是一個類模板。像 Queue 類中任何其他成員一樣,QueueItem的模板形參與其外圍類(Queue 類)的模板形參相同。

 

在其類外部定義的嵌套類成員,不能定義在外圍類內部,必須定義在定義外圍類的同一範圍中。

成員的名字在類外部是不可見的。要定義QueueItem的建構函式,必須指出,QueueItem 是 Queue 類範圍中的嵌套類:

template <class Type>Queue<Type>::QueueItem::QueueItem(const Type &t):item(t), next(0) { }

這段代碼定義了一個函數模板,以名為 Type 的單個類型形參化為形參。從右至左讀函數的名字,這個函數是 QueueItem 類的建構函式,QueueItem 類嵌套在Queue<Type> 類的範圍中。

 

如果 QueueItem 類聲明了一個靜態成員,它的定義也需要放在外層範圍中。假定 QueueItem 類有一個靜態成員,它的定義看起來可能像下面這樣:

template <class Type>int Queue<Type>::QueueItem::static_mem = 1024;

 

執行個體化外圍類模板的時候,不會自動執行個體化類模板的嵌套類。像任何成員函數一樣,只有當在需要完整類類型的情況下使用嵌套類本身的時候,才會執行個體化嵌套類。例如,像Queue<int> qi; 這樣的定義,用 int 類型執行個體化了 Queue 模板,但沒有執行個體化QueueItem<int> 類型。成員 head 和 tail 是指向 QueueItem<int> 指標,這裡不需要執行個體化 QueueItem<int> 來定義那個類的指標。只有當 Queue<int> 類的成員函數中對 head 和 tail 解引用的時候,才執行個體化 Queue<int> 類。

 

2:名字尋找

對嵌套類中所用名字的名字尋找在普通類的名字尋找之前進行,現在唯一的區別是可能要尋找一個或多個外圍類範圍。

作為嵌套類中名字尋找的例子,考慮下面的類聲明:

class Outer {public:    struct Inner {        // ok: reference to incomplete class        void process(const Outer&);        Inner2 val; // error: Outer::Inner2 not in scope    };        class Inner2 {    public:        // ok: Inner2::val used in definition        Inner2(int i = 0): val(i) { }        // ok: definition of process compiled after enclosing class is complete        void process(const Outer &out) { out.handle(); }    private:        int val;    };        void handle() const; // member of class Outer};

編譯器首先處理 Outer 類成員的聲明 Outer::Inner 和 Outer::Inner2。

將名字 Outer 作為 Inner::process 形參的使用被綁定到外圍類,在看到process 的聲明時,那個類仍是不完整的,但形參是一個引用,所以這個使用是正確的。

資料成員 Inner::val 的聲明是錯誤的,還沒有看到 Inner2 類型。

Inner2 中的聲明看來沒有問題——它們大多隻使用內建類型 int。唯一的例外是成員函數 process,它的形參確定為不完全類型 Outer。因為其形參是一個引用,所以 Outer 為不完全類型是無關緊要的。

直到看到了外圍類中的其餘聲明之後,編譯器才處理建構函式和 process成員的定義。

當編譯器尋找 Inner2 類中的定義所用的名字時,Inner2 類和 Outer 類中的所有名字都在範圍中。val 的使用(出現在 val 的聲明之前)是正確的:

將該引用綁定到 Inner2 類中的資料成員。同樣,Inner2::process 成員函數體中對 Outer 類的 handle 的使用也正確,當編譯 Inner2 類的成員的時候,整個 Outer 類在範圍中。

C++嵌套類

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.