塞翁失马,焉知非福?《淮南子·人间训》
C++中可以将一个类的的声明放在另一个类中。 在另一个类中被声明的类叫做“嵌套类| nested classs”,它通过提供新的 类型类 作用域来避免名称混乱。
假设有类A, 类B在A中被定义,则A类的成员函数可以创建和使用B的对象; 仅当B的定义在A的public部分时,才能在A的外面使用B类,且必须必须使用作用域解析操作符。
对类进行嵌套是为了帮助实现另一个类,避免名称冲突。
Example:
class Queue
{
class Node
{
public:
int item;
Node* next;
//Node(const int& i) :item(i), next(0) {}
Node(const int& i);
};
//...
bool enqueue(const int& item);
};
//cpp file:
Queue::Node::Node(const int& i) //使用两层作用域解析符号
{
item = i;
next = 0; //将next指针置为0,这是使用c++编写空值指针的方法之一,使用NULL时,必须包含一个定义NULL的头文件。
}
bool Queue::enqueue(const int& item)
{
//...
Node* add = new Node(item); //创建嵌套类的对象啦。
//...
return true;
}
嵌套类作用域:
如果类B在类A的private部分被声明,则只有类A知道B的存在。在外面定义B的对象的话,A::B obj 会报错; 在A的成员函数内部,A::B obj 不会报错。
A的派生类也不知道也不能使用B类,因为派生类不能直接访问基类的私有部分。
表格:
嵌套类的访问控制:
在上面的例子中,Node类没有赋予Queue类任何对Node类的访问特权, 因此Node类对象的public成员才能被外部访问(即假设有Node类的对象obj,只能ojb.f,其中f为Node类的public成员)。
模板中的嵌套:
上面的Queue类转换为模板类时,是否会由于它包含嵌套类而带来问题? --- 不会。
Example2:
template <class Item>
class QueueTP
{
private:
enum {Q_SIZE = 10};
class Node
{
Item item;
Node* next;
Node(const Item& i) :item(i), next(0)
{
}
};
public:
bool enqueue(const Item& item);
};
//cpp:
template <class Item>
bool QueueTP<Item>::enqueue(const Item& item)
{
Node* add = new Node(item);//创建嵌套类的对象啦。不用Node<>
//...
return true;
}
Reference:
《C++ Primer Plus 第五版--15.2》