上一篇:http://www.BkJia.com/kf/201201/116156.html
18.4 嵌套類
可以在另一個類內部定義一個類,這樣的類是嵌套類(nested class),也稱為嵌套類型(nested type)。嵌套類最常用於定義執行類。
嵌套類是獨立的類,基本上與它們的外圍類不相關,因此,外圍類與嵌套類的對象是相互獨立的。嵌套類型的對象不具有外圍類所定義的成員,同樣,外圍類的成員也不具備嵌套類所定義的成員。
嵌套類的名字在其外圍類的作用域中可見,但在其他類作用域或定義外圍類的作用域中不可見。嵌套類的名字將不會與另一作用域中聲明的名字沖突。
嵌套類可以具有與非嵌套類相同種類的成員。像其任何他類一樣,嵌套類使用訪問標號控制對自己成員的訪問。成員可以聲明為public、private或protected。外圍類對嵌套類的成員沒有特殊訪問權,並且嵌套類對其外圍類的成員也沒有特殊訪問權。
嵌套類定義了其外圍類的一個類型成員。像任何其他成員一樣,外圍類決定對這個類型的訪問。在外圍類的public部分定義的嵌套類定義了可在任何地方使用的類型,在外圍類的protected部分定義的嵌套類定義了只能由外圍類、友元或派生類訪問的類型,在外圍類的private部分定義的嵌套類只能被外圍類或其友元訪問的類型。
18.4.1 嵌套類的實現
namespace MyNamespace
{
template<class T>
class Queue{
private:
struct QueueItem{
QueueItem(const T&);
T item;
QueueItem *next;
};
QueueItem *head;
QueueItem *tail;
};
}
1. 嵌套在類模板內部的類是模板
2. 定義嵌套類的成員
在其類外部定義的嵌套類成員,必須定義在定義外圍類的同一作用域中。在其類外部定義的嵌套類的成員,不能定義在外圍類內部,嵌套類的成員不是外圍類的成員。
namespace MyNamespace
{
template<class T>
class Queue{
private:
struct QueueItem{
QueueItem(const T&);
T item;
QueueItem *next;
};
QueueItem *head;
QueueItem *tail;
};
template <class T>
Queue<T>::QueueItem::QueueItem(const T &t):item(0),next(0){
}
}
3. 在外圍類外部定義嵌套類
嵌套類支持外圍類的實現細節。我們可能希望防止外圍類的用戶看見嵌套類的實現代碼。正如可以在類定義體外部定義嵌套類的成員一樣,我們也可以在外圍類定義體的外部定義整個嵌套類。
namespace MyNamespace
{
template<class T>
class Queue{
private:
struct QueueItem;
QueueItem *head;
QueueItem *tail;
};
template<class T>
struct Queue<T>::QueueItem{
QueueItem(const T&);
T item;
QueueItem *next;
};
template <class T>
Queue<T>::QueueItem::QueueItem(const T &t):item(0),next(0){
}
}
在看到類定義體外部定義的嵌套類的實際定義之前,該類是不完全類型,應用所有使用不完全類型的常規規則。
4. 嵌套類靜態成員定義
namespace MyNamespace
{
template<class T>
class Queue{
private:
struct QueueItem;
QueueItem *head;
QueueItem *tail;
};
template<class T>
struct Queue<T>::QueueItem{
QueueItem(const T&);
T item;
QueueItem *next;
static int static_mem;
};
template<class T>
int Queue<T>::QueueItem::static_mem=1;
template <class T>
Queue<T>::QueueItem::QueueItem(const T &t):item(0),next(0){
}
}
5. 使用外圍類的成員
外圍作用域的對象與其嵌套類型的對象之間沒有聯系。
namespace MyNamespace1
{
template<class T>
class Queue{
private:
struct QueueItem;
QueueItem *head;
QueueItem *tail;
void *pop();
};
template<class T>
struct Queue<T>::QueueItem{
QueueItem(const T&);
T item;
QueueItem *next;
static int static_mem;
};
template<class T>
int Queue<T>::QueueItem::static_mem=1;
template<class T>
Queue<T>::QueueItem::QueueItem(const T &t):item(0),next(0){
}
template<class T>
void *Queue<T>::pop()
{
QueueItem *p=head;
head=head->next;
delete p;
}
}
6. 使用靜態成員或其他類型的成員
嵌套類可以直接引用外圍類的靜態成員、類型名和枚舉成員,當然,引用外圍類作用域之外的類型名或靜態成員,需要作用域確定操作符。
7. 嵌套模板的實例化
實例化外圍類模板的時候,不會自動實例化類模板的嵌套類。像任何成員函數一樣,只有當在需要完整類類型的情況下使用嵌套類本身的時候,才會實例化嵌套類。
18.4.2 嵌套類作用域中的名字查找
對嵌套類中所用名字的名字查找在普通類的名在查找之前進行,現在唯一的區別是可能要查找一個或多個外圍類作用域。
當處理類成員處理時,所用的任意名字必須出現在使用之前。當處理定義的時候,整個嵌套類和外圍類均在作用域中。
使用作用域操作符控制名字查找
可以使用作用域操作符訪問外圍作用域。
摘自 xufei96的專欄