建構子與除構子
- Constructor (建構子) 與 destructor (除構子): 類別中特殊的成員函數, 編譯器會對它們作特殊的處理. 請參考 complex.cc, vector.cc, 與 creature.cc.
- 功用: 希望 (半自動或全自動地) 對每個變數做起始與清除的動作, 通常對應到 C 程式中名稱為 init/open/begin/start/... 與 shutdown/close/end/stop/... 等函數. 類似觀念: 視窗程式設計中的 open 與 close 等 event (事件) 的 script (腳本)
-
執行時機
- constructor: 變數生命開始時 (即自系統取得記憶空間時). 無參數的 constructor 自動執行; 有參數的 constructor 手動執行.
- destructor: 變數生命結束前 (將記憶空間還給系統前). 一律沒有參數, 系統會在適當時機自動呼叫.
- 靜態變數: 進出整個程式時.
- 自動變數: 進出 block 時.
- free store 上的變數: new 與 delete 時.
-
宣告方式
- Constructor 名稱與類別名稱相同, 不可以有傳回值 (連 void 都不寫), 不應宣告為 const. 可以有好幾個 signature 不同的 constructors.
- Destructor 名稱與類別名稱相同, 但前面多了 ~. 一個類別只能有一個 destructor, 且不可以有傳回值 (連 void 都不寫), 不應宣告為 const, 也不可以有參數.
- 宣告可接受單一參數的 constructor (包含有多餘的內定參數者) 時, 記得在 constructor 名稱前面加上 explicit 這個 keyword; 稍後再解釋何時不必加. (定義處不要寫 explicit)
-
如何呼叫 constructor
- 宣告變數時, 例:
complex x(3,-4), y(2,-1);
注意: local static 變數的 constructor 在該副程式第一次執行時起動. - 以 new 產生變數時, 例:
p = new complex(4,-3);
-
在 "上級" 類別的 constructor 中, "脖子" 處, 呼叫 "下級"
類別的 constructor, 例:
explicit comlpex(double r, double i=0) : re(r), im(i) { }
(稱為 constructor initializer) 以這個例子而言, 其實效果和explicit complex(double r, double i=0) { re = r; im = i; }
一樣. 但是 constructor initializer 的寫法比較具有一般性, 在很多情況下非用它不可, 例如- data member 又是一個使用者自定的類別;
- data member 是一個 reference
- data member 是一個 const
- 在 initialize base class member 時 (見繼承單元)
- 產生用畢即棄的臨時變數, 例:
complex(3,4).print();
或return complex(re + b.re, im + b.im);
或return complex(abs * cos(angle), abs * sin(angle));
- 注意: 即使宣告變數或使用 new 時不傳參數, 仍舊有一個 constructor 會自動執行 -- 也就是那個不需要參數的 constructor.
- 宣告變數時, 例:
- 如何呼叫 destructor: No, never do that!
-
Copy constructor (複製建構子)
- 宣告方式:
complex(complex const & x)
-
執行時機:
- 給新宣告的變數設定起始值, 以舊的變數為範本, 例:
complex x(3,4); complex y(x);
- 以值傳遞參數.
- 參數傳回值.
- 給新宣告的變數設定起始值, 以舊的變數為範本, 例:
- 注意: 在變數宣告中,
complex y = x;
會呼叫到 copy constructor; 但是在程式中,y = x;
呼叫到的則是 assignment operator.
- 宣告方式:
-
以下四個特殊成員函數與 memory allocation 有關, 且同一個類別中,
修改這四個成員函數的程式碼時, 往往必須一起考慮.
- Constructor: new
- Destructor: delete
- Copy constructor: new, copy
- Assignment operator: (delete, new,) copy (記得檢查 src 與 dst 相同的特殊狀況.)
-
內建版的特殊成員函數
- 上述四個特殊的 member functions 都有內建版. 內建的 constructor (沒有參數) 與 destructor 什麼都不作; 內建的 copy constructor 做的是: "逐一呼叫每個資料成員的 copy constructor"; 內建的 assignment operator 做的是: "逐一呼叫每個資料成員的 assignment operator". 在最底層 (也就是 int, double, char, ... 等內建型別) 的 copy constructor 與 assignment operator 都是直接拷貝整個變數.
- 如果程式設計師宣告了任何一個 constructor (不論是有參數的版本或沒有參數的版本), 則內建的 (沒有參數的) constructor 自動消失.
- 如果程式中需要宣告某一類別的陣列變數, 則該類別一定要有一個不具參數的 constructor (內建的或程式設計師定義的皆可)
- 在一個 composite class 中 (即類別的 data member 本身又是一個使用者自定的類別), 層層疊疊的 constructors 的呼叫順序是由下而上; 而 destructors 的呼叫順序則是由上而下. (想像蓋房子與拆房子的順序)
- 本頁最新版網址: https://frdm.cyut.edu.tw/~ckhung/b/cxx/constructor.php; 您所看到的版本: February 14 2012 10:32:25.
- 作者: 朝陽科技大學 資訊管理系 洪朝貴
- 寶貝你我的地球, 請 減少列印, 多用背面, 丟棄時做垃圾分類。
- 本文件以 Creative Commons Attribution-ShareAlike License 或以 Free Document License 方式公開授權大眾自由複製/修改/散佈。