C++設計一個不含指針的類還是比較簡單的,因為它不需要考慮一下三大因素(也叫Big Three): destructor copy constructor copy assignment Operator 為什么呢?因為不含指針的話,淺拷貝(memberwise copy)就可以了,不會涉及到同一塊內存被多個對象指向的問題,析構的時候也不需要考慮內存的操作。
舉例complex類如下: *class complex //class head { //class body public: complex (double r = 0, double i = 0): re (r), im (i) { } complex& operator += (const complex&); double real () const { return re; } double imag () const { return im; } PRivate: double re, im; friend complex& __doapl (complex *, const complex&); };*
這里有幾個需要注意的地方: 1) real()和imag()在類的體內定義,則自動成為inline函數。如果在體外定義,則需要顯式聲明inline才會成為inline函數。
2) friend函數本身不是類的一部分,friend是指此函數可以自由訪問該類的private成員。friend也可以用在類上面,一個類的friend類的object可以訪問該類的private成員。注意: 同一個類的各個object互為friend,這也是為什么拷貝構造函數和賦值構造函數可以實現的基礎。
friend函數有什么好處呢?因為friend函數不需要通過class來訪問,比用class函數來做效率更高。
3) complex定義了自己的缺省構造函數。 complex (double r = 0, double i = 0): re (r), im (i) { } 所謂缺省構造函數是指對象的創建不需要參數就可調用的構造函數。C++標準規定,如果構造函數沒有參數,或者構造函數的所有參數都有缺省值,則算作缺省構造函數。
如果complex沒有定義自己的缺省構造函數,C++編譯器會自動給它生成一個缺省構造函數類似, complex() {} 注意該函數什么也不做。
如果complex的缺省構造函數為complex(double r=0, double i=0): re(r), im(i) {},并且沒有其他缺省構造函數,代碼 complex c1; 會調用該構造函數,并用re和im的缺省參數。
如果complex的構造函數為complex(double r, double i): re(r), im(i) {}, 并且沒有其他缺省構造函數,代碼 complex c1; 會編譯出錯,因為編譯器不知道把什么值賦給re和im。
如果complex的缺省構造函數為complex() {}, 并且沒有其他缺省構造函數,代碼 complex c1; 會調用該缺省構造函數。
如果complex 有兩個缺省構造函數, complex() {} complex(double r=0, double i=0): re(r), im(i) {} 代碼complex c1編譯會出錯,因為編譯器不知道調用那個缺省構造函數。
如果complex有以下兩個構造函數,注意第一個為缺省構造函數,第二個不是。它們可以共存。 complex() {} complex(double r, double i): re(r), im(i) {} 代碼complex c1;編譯會通過,編譯器會采用complex() {}作為缺省構造函數。
4) 下面幾種寫法要特別注意它們的區別: complex c1(): 聲明一個名為c1的函數, 該函數返回complex類型。注意這里不是創建complex 類的對象 complex c1; //創建一個complex的一個名為c1的obj, 并且會調用complex 類中的缺省構造函數,其缺省參數為(0,0). complex(); //創建一個complex的臨時對象,此處會調用complex 類中的缺省構造函數,同樣,int()也是創建一個int的臨時對象 complex c1=complex(); //創建一個complex的臨時對象,并賦給c1,此處會調用賦值構造函數 complex *p=new complex();//創建一個complex的obj,這里會調用complex類中的缺省構造函數,并用指針p指向它。
5) complex重載了+=操作符。操作符重載可以看成是一個特殊的函數,給C++編程帶來很大便利。
操作符重載可以是類成員函數,也可以是非類成員函數。如果是object自身與complex的其它object相加,可寫成類成員函數,如上面的這種情況; 但如果不是object自身與complex其他object相加,則不能寫成類成員函數。
如果是成員函數的話,默認第一個參數是this指針,通常不寫。注意:操作符重載一定是作用在左邊的操作符。
6) 上面operator+重載函數參數采用傳引用。 對于函數入口參數,盡量用傳引用,因為傳值的話,value會放進stack,應該盡量少用。 另外,對于函數返回值也是盡量返回reference,但如果函數返回的是在棧上分配的一個local變量或object,則不能返回reference,因為該local變量或obj已經被刪除。
7) 上面operator+的入口參數加了const。對于函數入口參數,如果函數不會改變這個參數,則該參數可以加const。 另外,如果某類函數不會改變函數的數據成員,則可以在函數名后加const,比如上面的real()和imag()函數。
新聞熱點
疑難解答