1、在一个类内部再定义另外一个类,这样的类称为嵌套类(nested class),也称为嵌套类型(nested type)。嵌套类最常用于执行类。
嵌套类是独立的类,基本上与它们的外围类不相关,因此,外围类和嵌套类的对象是互相独立的。嵌套类型的对象不具备外围类所定义的成员,同样,外围类的成员也不具备嵌套类所定义的成员。
示例代码
template <class Type> class Queue { //interface functions to Queue are unchanged 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; // value stored in this element QueueItem *next; // pointer to next element in the Queue }; QueueItem *head; // pointer to first element in Queue QueueItem *tail; // pointer to last element in Queue }; template <class Type> Queue<Type>::QueueItem::QueueItem(const Type &t):Item(t), next(0) { }
2、嵌套在类模板内部的类是模板。嵌套类模板的实例化与外围类模板的实例化之间的映射是一对一的。
在其类外部定义的嵌套类成员,必须定义在定义外围类的同一作用域中。在基类外部定义的嵌套类的成员,不能定义在外围类内部,嵌套类的成员不是外围类的成员。
示例代码
#include <iostream> using namespace std; template <class Type> class Queue { //interface functions to Queue are unchanged public: void Pop(); 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 *head; // pointer to first element in Queue QueueItem *tail; // pointer to last element in Queue }; template <class Type> struct Queue<Type>::QueueItem { QueueItem(const Type&): Item(t), next(0){}; Type Item; // value stored in this element QueueItem *next; // pointer to next element in the Queue static int static_mem; }; template <class Type> int Queue<Type>::QueueItem::static_mem = 1024; template <class Type> void Queue<Type>::Pop() { QueueItem *p = head; head = head->next; delete p; } int main() { return 1; }
从右至左读函数的名字。
3、正如可以在类定义体外部定义嵌套类的成员一样,我们也可以在外围类定义体的外部定义整个嵌套类。
4、如果嵌套类声明了一个静态成员,它的定义也需要放在外层作用域中。
5、外围作用域的对象与嵌套类型的对象之间没有联系。
嵌套类中的非静态函数具有隐含的this指针,指向嵌套类型的对象。嵌套类型对象只包含嵌套类型的成员,不能使用this指针获取外围类的成员。同样,外围类中的非静态成员函数也具有this指针,它指向外围类型的对象,该对象只具有外围类中定义的成员。
6、嵌套类可以直接引用外围类的静态成员、类型名和枚举成员。引用外围作用域之外的类型名或静态成员,需要作用域确定操作符。
7、实例化外围类模板的时候,不会自动实例化类模板内的嵌套类。像成员函数一样,只有当在需要完整类类型的情况下使用嵌套类本身的时候,才会实例化嵌套类。上述例子中,Queue<int> qi; 只实例化Queue<int>但是并不实例QueueItem<int>,只有在Queue<int>类的成员函数中对head,tail解引用时,才实例化QueueItem<int>类。
8、对嵌套类中所用名字的名字查找,在普通类的名字查找之前进行。当处理类成员声明的时候,所用的任意名字必须在使用之前出现。当处理定义的时候,整个嵌套类和外围类都在作用域中。