第15章 友元、異常和其它
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
主要內容:
1)友元類
2)友元類方法
3)嵌套類
4)引發異常、try塊和catch塊
5)異常類
6)運行階段類型識別(RTTI)
7)dynamic_cast和typeid
8)static_cast、const_cast和reiterpret_cast
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1、對於Remote對象的TV方法,其原型可在Remote類聲明之前聲明,但必須在Remote類聲明之後定義,以便編譯器有足夠的信息來編譯該方法。
class Tv
{
friend class Remote;
public:
void buzz(Remote & r);
……
};
class Remote
{
friend class Tv:
public:
void Bool volup(Tv & t)
{
t.volup();
}
};
inline void Tv::buzz(Remote & r)
{
……
}
由於Remote的聲明位於Tv聲明的後面,所以可以在類聲明中定義Remote::volup(),但是Tv::buzz方法必須在Tv聲明的外部定義,使其位於Remote聲明的後面。
共同的友元
需要使用友元的另一種情況是,函數需要訪問兩個類的私有數據,從邏輯上看,這樣的函數應是每個類的成員函數,但這是不可能的,它可以是一個類的成員,同時是另一個類的友元,不過有時將函數作為兩個類的友元更加合理。
補充:友元使得能夠為類開發更靈活的接口
2、嵌套類
在C++中,可以將類聲明放在另一個類中,在另一個類中聲明的類被稱為嵌套類(nested class),它通過提供新的類型類作用域來避免名稱的混亂。
對類進行嵌套通常是為了幫助實現另一個類,避免名稱沖突。
補充:嵌套類是在其他類中聲明的類,它有助於設計這樣的助手類,即實現其他類,但不必是公有接口的組成部分。
class Queue
{
//class scope definitions
//Node is a nested structure definition local to this class
struct Node
{
Item item;
struct Node * nest;
};
}
Node實際上是一個嵌套類。
1)嵌套類的作用域
如果嵌套類是私有部分聲明的,則只有後者知道它。前面Node類就是這種情況,因為類的默認訪問權限是私有的;對於包含它的類是可以使用它;從包含它的類派生而來的類不能使用,外部世界也不能使用它。
如果嵌套類是保護分聲明的,則只有後者知道它。對於包含它的類是可以使用它;從包含它的類派生而來的類能使用,外部世界也不能使用它。
如果嵌套類是公部分聲明的,對於包含它的類是可以使用它;從包含它的類派生而來的類能使用,外部世界也能使用它。
嵌套結構和枚舉的作用域與這個相同。
3、異常
1)調用abort
處理方式,如果其中一個參數是另一個參數的負值,則調用abort()函數
其典型實現是向標准錯誤流發送消息abnormal program termination(程序異常終止)
2)返回錯誤碼
一種比異常終止更加靈活的方法是使用函數的返回值來指出問題。
3)異常機制
對於異常處理有三個組成部分
①引發異常
throw語句實際上是跳轉,關鍵字表示引發異常,緊跟其後的值指出了異常的特征
②捕獲有處理程序的異常
catch關鍵字表示捕獲異常
③使用try塊
try塊標識其中特定的異常可能被激活的代碼塊,它後面跟一個或多個catch塊
補充:C++異常機制為處理拙劣的編程事件,如不適合的值,I/O失敗等,提供了一種靈活的方式,引發異常將終止當前執行的函數,將控制權傳給匹配的catch塊。catch塊緊跟在try塊中的代碼。
4、RTTI
RTTI是運行階段類型識別
RTTI特性讓程序能夠檢測對象的類型,dynamic_cast操作符用於將派生類指針轉換為基類指針,其主要用途是確保可以安全的調用虛函數。
RTTI的工作原理:
C++有3個支持的RTTI的元素,
如果可能的話,dynamic_cast操作符將使用一個指向基類的指針來生成一個指向派生類的指針,否則,該操作符返回0——空指針。
typeid操作符返回一個指出對象的類型的值
type_info結構存儲了有關特定類型的信息
RTTI只適用於包含虛函數的類。
通常,如果指向的對象(*pt)的類型是Type或者是從Type直接或間接派生而來的類型,則表達式:dynamic_cast