塞翁失馬,焉知非福?《淮南子·人間訓》
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》