|
|
int)的不同變數被應用了加法運算子,然後是賦值運算子。對於基本的算術型別,這類操作的含義通常是顯而易見且無歧義的,但對於某些類型別可能並非如此。例如: |
|
b 和 c 進行加法運算的結果並不明顯。實際上,僅這段程式碼就會導致編譯錯誤,因為 myclass 型別沒有為加法定義任何行為。然而,C++ 允許大多數運算子被過載,以便可以為幾乎任何型別(包括類)定義其行為。以下是可以被過載的所有運算子的列表:| 可過載的運算子 |
|---|
|
operator 函式進行過載,這些函式是具有特殊名稱的常規函式:它們的名稱以 operator 關鍵字開頭,後跟被過載的*運算子符號*。語法是:type operator sign (parameters) { /*... 函式體 ...*/ }
x 和 y。兩個*笛卡爾向量*的加法運算定義為它們的 x 座標相加,以及它們的 y 座標相加。例如,將*笛卡爾向量* (3,1) 和 (1,2) 相加會得到 (3+1,1+2) = (4,3)。這可以用 C++ 實現如下程式碼: |
|
4,3 |
CVector 的出現感到困惑,請注意其中一些指的是類名(即型別)CVector,而另一些是同名函式(即建構函式,其名稱必須與類名相同)。例如: |
|
CVector 類的函式 operator+ 過載了該型別的加法運算子(+)。一旦宣告,這個函式就可以透過運算子隱式呼叫,或者透過其函式名顯式呼叫: |
|
operator+ 實際上執行減法,或者過載 operator== 來用零填充物件,這在語法上是完全有效的,儘管使用這樣的類可能會很有挑戰性。operator+ 這樣的操作,成員函式過載所期望的引數自然是運算子右側的運算元。這對於所有二元運算子(即左側有一個運算元,右側也有一個運算元的運算子)都是通用的。但是運算子可以有多種形式。下表總結了每種可過載的不同運算子所需的引數(請將每種情況下的 @ 替換為相應的運算子):| 表示式 | 運算子 | 成員函式 | 非成員函式 |
|---|---|---|---|
@a | + - * & ! ~ ++ -- | A::operator@() | operator@(A) |
a@ | ++ -- | A::operator@(int) | operator@(A,int) |
a@b | + - * / % ^ & | < > == != <= >= << >> && || , | A::operator@(B) | operator@(A,B) |
a@b | = += -= *= /= %= ^= &= |= <<= >>= [] | A::operator@(B) | - |
a(b,c...) | () | A::operator()(B,C...) | - |
a->b | -> | A::operator->() | - |
(TYPE) a | TYPE | A::operator TYPE() | - |
a 是 A 類的物件,b 是 B 類的物件,c 是 C 類的物件。TYPE 是任意型別(該運算子過載了到 TYPE 型別的轉換)。operator+ 示例中使用。但某些運算子也可以作為非成員函式過載;在這種情況下,運算子函式將相應類的物件作為其第一個引數。 |
|
4,3 |
this 代表一個指向其成員函式正在被執行的物件的指標。它在類的成員函式內部使用,以引用物件本身。 |
|
yes, &a is b |
operator= 成員函式中。繼續看前面*笛卡爾向量*的例子,它的 operator= 函式可以這樣定義: |
|
operator= 隱式生成的程式碼非常相似。 |
|
6 7 |
|
|
|
|
Dummy 類中所有物件共享的靜態變數 n。this。const 物件時: |
|
const。但請注意,建構函式仍然會被呼叫,並被允許初始化和修改這些資料成員: |
|
10 |
const 物件的成員函式只有在它們本身被指定為 const 成員時才能被呼叫;在上面的例子中,成員函式 get(沒有被指定為 const)不能從 foo 呼叫。要將一個成員函式指定為 const 成員,const 關鍵字應緊跟在函式原型引數的右括號之後: |
|
const 可以用來限定成員函式返回的型別。這個 const 與指定成員為 const 的那個不同。兩者是獨立的,並位於函式原型中的不同位置: |
|
const 的成員函式不能修改非靜態資料成員,也不能呼叫其他非 const 成員函式。本質上,const 成員不應修改物件的狀態。const 物件只能訪問標記為 const 的成員函式,但非 const 物件不受限制,因此可以訪問 const 和非 const 成員函式。const 物件,因此把所有不修改物件的成員標記為 const 是不值得的,但實際上 const 物件非常普遍。大多數接受類作為引數的函式實際上是透過 const 引用來接受它們的,因此,這些函式只能訪問它們的 const 成員: |
|
10 |
get 沒有被指定為 const 成員,那麼在 print 函式中呼叫 arg.get() 是不可能的,因為 const 物件只能訪問 const 成員函式。const 而另一個不是。在這種情況下,當物件本身是 const 時,呼叫 const 版本;當物件本身是非 const 時,呼叫非 const 版本。 |
|
15 20 |
|
|
int 的整數值 115 和 36,我們會這樣寫: |
|
|
|
template <...> 字首開頭: |
|
100 |
getmax 定義的語法: |
|
T 搞糊塗了嗎?這個宣告中有三個 T:第一個是模板引數。第二個 T 指的是函式返回的型別。第三個 T(尖括號中的那個)也是必需的:它指定了這個函式的模板引數也是類模板的引數。mycontainer,它可以儲存任何型別的一個元素,並且只有一個名為 increase 的成員函式,該函式會增加其值。但我們發現,當它儲存一個 char 型別的元素時,擁有一個帶有 uppercase 成員函式的完全不同的實現會更方便,所以我們決定為該型別宣告一個類模板特化: |
|
8 J |
|
|
template<>,包含一個空的引數列表。這是因為所有型別都是已知的,這個特化不需要模板引數,但它仍然是類模板的一個特化,因此需要這樣標記。<char> 特化引數。這個特化引數本身標識了模板類被特化的型別(char)。注意通用類模板和特化之間的區別: |
|
類 (I) | 目錄 | 特殊成員 |