類別(Class)由成員(member)組成,包括資料、函數以及建構函數。
我們可以把Class當成是一個學生,而這個學生有姓名、身高、體重、年齡,有個函數可以來計算它的BMI,也要有一個函數可以「創建」這個學生。以下為範例:
建構函數有兩種寫法,一是直接用函數寫,另外則是利用 :
來初始化成員變數
初始化列表(各變數以,
分隔):
通常初始化列表較常用在 const 成員上,因為 const 成員不可賦值
通常用在需要釋放記憶體之成員函數:student::~student() {}
定義成員函數:
呼叫成員函數:
在 Vector2D 中,有兩個 double 的值,分別代表座標的 x, y,以及基本的初始化函數:
通常,我們會將 class 內的變數設為 private,以避免外部經任意手段更改。
因為變數不可存取,我們需要另外寫一個函數來取得他們的值:
延續上面的例子,事實上,this
是一個指標型態
因為 this
是指標型態,並且 .
的優先順序在 *
之前,因此我們需要用 (*this).getX()
來呼叫函數,但這樣顯得過於麻煩,因此C++提供了一個好方法:this->getX()
我想有人看到 const
可能會不懂它是什麼東西
const
是一個關鍵字,它的用途就是讓指定物件或變數不可修改
講白就是被 const
修飾 (decorate)過的不能被賦值 (assign)
那如果把函數傳入的參數加上個const
會變成怎樣呢?
那如果再把參數改成傳引用(reference)呢
這樣有什麼好處呢?
因為用 const
修飾過,所以參數會受到保護,免得被亂改,傳入引用會讓效率變高且減少空間需求(在物件所佔的空間較大會比較明顯
再之後的get函數中會在函數後面加個 const
,那這又是什麼呢?
這個 const
表示getX()不會修改成員變數
如果要函數傳進去的物件是有 const
修飾過的,那這個物件只能調用 const
修飾過的函數 (誰聽得懂,直接上code)
講了這麼多 const
的用途,看起來挺麻煩的
但適當的加 const
可以讓程式的穩定性更加,速度也會提升 (也可以提醒自己,這個東西是不能亂改的啊),請各位謹記
我想各位在 const
篇應該有看到 &
這個符號吧,想必又是看不懂了 (這作者到底怎樣,都喜歡先斬後奏的)
「引用」就是一個變數的別名 (alias),它一定會指向一個變數,且引用是跟變數共用相同記憶體區域的,當讀取這個別名時,就可以得到它所指向的變數 (variable) 的值 (value) 了
呃,有聽沒有懂,直接上code🤣
由上述code可得知,引用必須要指向一個變數,且修改引用的值就等於修改引用的變數的值,這有什麼好處呢?
因為需要指向變數,所以就不存在初始化 (initialization)的問題,不用擔心引用裡面會存什麼自己不知道的東西
另外,因為引用是共用記憶體區域的,所以在傳參數時傳入引用是可以減少記憶體開銷的
上述就是使用引用來達成交換函數的功能,上面也顯示了
一般傳入參數會是複製一份新的給函數使用,而傳引用則是直接使用外部的參數使用,這對記憶體開銷會比較小一點
那問題來了,因為會直接修改到外面的參數,那要怎麼避免呢?請回去看 cosnt
篇 🤣
有關&
的注意事項:
函數返回值時不可以返回區域引用,會出事的,至於原因各位可以想想
接下來,我要隆重介紹一個非常重要的一種函數——運算子(operator)
運算子是一個符號,也是一種函數,它可以告訴編譯器執行指定的數學關係或邏輯運算並產生結果。
在C++中,部分運算子是可以被重載(overloading)的
關於可重載的列表見維基百科 運算子優先級與可重載的運算子列表
直接舉個例子吧。延續上面的 Vector2D
,現在我們想要將兩個向量相加,那麼我們應該這樣寫:
這樣的意思是要把 *this
跟 other
相加,因此,若我們將其使用後會是這樣:
有兩種寫法:
特別注意:如果是在成員函數內,可直接取用 class 內的 private 成員
那如果我想寫 int + Vector2D
呢?
事實上,operator也可以當作一般函數定義:
特別注意,這個函數不須寫在 class 中。
單元運算子分成兩種,一是加在變數前面,另一則是加在後面
加在前面的像是:負號 -x
、邏輯反 !x
;加在後面的則像是:後綴遞增 x++
特別注意 int
一定要加
現在請寫一個 class 叫做 complex,裡面包括:
舉另一個例子吧,假設我有一個 class 要來存儲一個交通工具,但我同時有汽車、公車、飛機,如果分開寫,那就太麻煩了。因此,我們先寫好共同的項目,再用「繼承」寫個別的東西。
如此一來,我們不需要把所有交通具都寫出來,而只需要寫一個大綱,在繼承出去寫細項即可。
tutorials