嵌套類就是在一個類(能夠稱爲外圍類)中又定義一個類,如:函數
class A{ int a; class B{int b;}; }; /* A就是外圍類 * B就是嵌套類 */
這個主要體如今兩個方面:spa
嵌套類對象中不會含有外圍類的成員,外圍類的對象也不會含有嵌套類的成員,如:A a1,B b1;則a1中不會有B::b這個成員,b1中也不會有A::a這個成員code
嵌套類對外圍類成員的訪問並無特殊權限,也是隻能訪問外圍類的public成員,外圍類對嵌套類成員的訪問也是如此對象
因此具備數據成員與函數成員的性質:
get
定義在外圍類public區域的嵌套類能夠在程序的任何地方使用編譯器
定義在外圍類protected區域的嵌套類僅能在外圍類及其子類以及友元中使用io
定義在外圍類private區域的嵌套類僅能在外圍類及其友元中使用編譯
#include <stdio.h> class A{ friend int main(int argc,char *argv[]); protected: class B{}; }; int main(int argc,char *argv[]){ A::B b; /* main是A的友元函數,因此可使用B類類型 * 使用B類類型須要加上A限定符,由於B是A的靜態成員嘛.. */ return 0; }
若外圍類是模板類,則其內部類也隱式的是模板類,但因爲內部類並無用'template<..>'修飾,因此相似'內部類名<Type>'是非法的!!模板
事實上只要肯定了外圍類的模板形參,則內部類內部使用的模板形參也即肯定了.因此沒有必要出現'內部類<Type>'class
template<typename ElemT> class Queue{ struct _QueueItem{ ElemT _data;/* 使用模板形參 ElemT 定義數據 */ _QueueItem *_next; }; public: /** value_type 也是 Queue 的類型成員. */ typedef ElemT value_type; private: _QueueItem *_head; /* 並非 _QueueItem<ElemT> */ _QueueItem *_tail; }; template<typename Type> inline const char* getTypeName( const Type & ) { return typeid(Type).name(); } #define PrintType(var) Println(#var ": %s",getTypeName(var)); int main( int argc,char *argv[] ){ Queue<int> i; i._head=new Queue<int>::_QueueItem; /* 並非 Queue<int>::_QueueItem<int> */ PrintType(i._head); PrintType(i._tail); PrintType(i._head->_next); Println("_QueueItem<int>*: %s",typeid(Queue<int>::_QueueItem*).name()); PrintType(i._head->_data); } /* --- 程序輸出 --- */ i._head: PN5QueueIiE10_QueueItemE i._tail: PN5QueueIiE10_QueueItemE i._head->_next: PN5QueueIiE10_QueueItemE _QueueItem<int>*: PN5QueueIiE10_QueueItemE i._head->_data: i
能夠看出 _head,_tail,_head->_next 的類型爲: _QueueItem<int*> 類型
_head->_data 的類型爲 int 類型
/* A.h */ #ifndef AAAA_H_ #define AAAA_H_ class A{ public: class B{ static int a; public: B(); void print(); }; private: static int a; public: A(); void print(); }; #endif /* A.cc */ #include "A.h" #include "stdio.h" int A::a=33; int A::B::a=77; A::A(){ ; } void A::print(){ printf("A\n"); return ; } /* 與常規類的外部定義也是同樣的,只不過對於內部類的訪問須要外部類限定符 * 由於內部類是外部類的類型成員 */ A::B::B(){ ; } void A::B::print(){ printf("B\n"); return ; }
將整個內部類都放在類的外部進行定義,如:
/* * A.h * * Created on: 2014年1月15日 * Author: Dreamlove */ #ifndef AAAA_H_ #define AAAA_H_ class A{ public: class B; private: static int a; B *b; public: A(); void print(); }; class A::B{ static int a; public: B(); void print(); }; #endif
要注意如下:
因爲在A中只是前沿聲明瞭B,因此B是不徹底類型!不能使用B來定義對象(由於B是不徹底類型,因此編譯器不知道爲B分配多少字節的空間);
內部類的完整定義必需要在外部類的完整定義下面,而且內部類名以前要有外部類名來限定,也能夠把內部類與外部類的定義分別放在兩個文件中:
/* A.h */ #ifndef AAAA_H_ #define AAAA_H_ class A{ public: class B; private: static int a; B *b; public: A(); void print(); }; /* B.h */ #ifndef BBBB_H_ #define BBBB_H_ #include "A.h" /* 由於外圍類的完整定義必需要在內部類以前 */ class A::B{ static int a; public: B(); void print(); }; #endif