第18章 特殊工具与技术(10)
上一篇:http://www.zzzyk.com/kf/201201/116156.html18.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. 嵌套模板的实例化
实例化外围类模板的时候,不会自动实例化类模板的嵌套类。像任何成员函数一样
补充:软件开发 , C++ ,