重載操做符與轉換

[0. 必須定義爲類成員的操做符]ios

賦值 =;
下標 [];
調用 ();
成員訪問箭頭 ->;算法

 

[1. 輸入和輸出操做符]數組

支持 I/O 操做的類所提供的 I/O 操做接口,
通常應該與標準庫 iostream 爲內置類型定義的接口相同,
所以,許多類都須要重載輸入和輸出操做符。函數

爲了與 IO 標準庫一致,操做符應接受 ostream& 做爲第一個形參,
對類類型 const 對象的引用做爲第二個形參,並返回對 ostream 形參的引用。post

重載輸出操做符通常的簡單定義以下:this

// general skeleton of the overloaded output operator
ostream&
operator <<(ostream& os, const ClassType &object)
{
// any special logic to prepare object

// actual output of members
os << // ...

// return ostream object
return os;
}


重載 "->" 必須返回指向類類型的指針,或者返回定義了本身的"->"的類類型對象。spa


[2. 定義自增/自減操做符]指針

C++ 語言不要求自增操做符或自減操做符必定做爲類的成員,
可是,由於這些操做符改變操做對象的狀態,因此更傾向於將它們做爲成員。code


在爲類定義重載的自增操做符和自減操做符以前,
還必須考慮爲咱們本身的類定義自增操做符和自減操做符的前綴和後綴操做符。對象

前綴式操做符的聲明,舉例以下:

class CheckedPtr {
public:
  CheckedPtr& operator++(); // prefix operators
  CheckedPtr& operator--();
  // other members as before
};

爲了與內置類型一致,前綴式操做符應返回被增量或減量對象的引用。

這個自增操做符根據 end 檢查 curr,從而確保用戶不能將 curr 增量到超過數組的末端。
若是 curr 增量到超過 end,就拋出一個 out_of_range 異常;
不然,將 curr 加 1 並返回對象引用(自減操做符的行爲與此相似):

// prefix: return reference to incremented/decremented object
CheckedPtr& CheckedPtr::operator++()
{
  if (curr == end)
    throw out_of_range
        ("increment past the end of CheckedPtr");
  ++curr; // advance current state
  return *this;
}

 

區別操做符的前綴和後綴形式

同時定義前綴式操做符和後綴式操做符存在一個問題:
它們的形參數目和類型相同,普通重載不能區別所定義的前綴式操做符仍是後綴式操做符。

爲了解決這一問題,後綴式操做符函數接受一個額外的(即,無用的)int 型形參。
使用後綴式操做符進,編譯器提供 0 做爲這個形參的實參。
儘管咱們的前綴式操做符函數可使用這個額外的形參,但一般不該該這樣作。
那個形參不是後綴式操做符的正常工做所須要的,它的惟一目的是使後綴函數與前綴函數區別開來。


接上面的例子,後綴式操做符以下:

class CheckedPtr {
public:
  // increment and decrement
  CheckedPtr operator++(int); // postfix operators
  CheckedPtr operator--(int);
  // other members as before
};

爲了與內置操做符一致,後綴式操做符應返回舊值(即,還沒有自增或自減的值),
而且,應做爲值返回,而不是返回引用。

後綴式操做符能夠這樣實現(後綴自減與此相似):

// postfix: increment/decrement object but return unchanged value
CheckedPtr CheckedPtr::operator++(int)
{
  // no check needed here, the call to prefix increment will do the check
  CheckedPtr ret(*this); // save current value
  ++*this; // advance one element, checking the increment
  return ret; // return saved state
}

操做符的後綴式比前綴式複雜一點,必須記住對象在 +1 或 -1 以前的狀態。
這些操做符定義了一個局部 CheckedPtr 對象,
將它初始化爲 *this 的副本,即 ret 是這個對象當前狀態的副本。

// Question:
  討論容許將空數組實參傳給 CheckedPtr 構造函數的優缺點。
// Answer:
  
優勢:構造函數的定義簡單
  缺點:致使所構造的對象有可能沒有指向有效的數組,從而失去其使用價值
  比較完善的作法是應該在構造函數中隊參數檢查。
// Question:
  爲何沒有定義自增和自減操做符的 const 版本?
// Answer:
  由於對 const 對象不能使用自增或自減操做。

 

[3. 類類型轉換和標準轉換]

使用轉換函數時,被轉換的類型沒必要與所須要的類型徹底匹配。
必要時可在類類型轉換以後跟上標準轉換以得到想要的類型。

注意:

1) 可是,類類型轉換以後不能再跟另外一個類類型轉換。
  若是須要多個類類型轉換,則代碼將出錯。

2) 既爲算術類型提供轉換函數,又爲同一類類型提供重載操做符,
  可能會致使重載操做符和內置操做符之間的二義性。

經過定義內置操做符的重載版本,咱們能夠爲本身的類型(即,類類型或枚舉類型)
的對象定義一樣豐富的表達式集合。
重載操做符必須具備至少一個類類型或枚舉類型的操做符。
應用於內置類型時,與對應操做符具備一樣數目的操做數、一樣的結合性和優先級。

大多數重載操做符能夠定義爲類成員或普通非成員函數,
賦值操做符、下標操做符、調用操做符和箭頭操做符必須爲類成員。
操做符定義爲成員時,它是普通成員函數。
具體而言,成員操做符有一個隱式 this 指針,該指針必定是第一個操做數,
即,一元操做符惟一的操做數,二元操做符的左操做數。

重載了 operator()(即,函數調用操做符)的類的對象,稱爲「函數對象」。
這種對象一般用於定義與標準算法結合使用的謂詞函數。

轉換操做符必須爲所轉換類的成員,無形參而且不定義返回值,轉換操做符返回操做符所具備類型的值。

相關文章
相關標籤/搜索