|
|
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) | ![]() 目錄 | ![]() 特殊成員 |