嵌套类就是在一个类(能够称为外围类)中又定义一个类,如:函数
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