乙個多月前把effective c++看完了,後來就是期末考試,一直沒有時間好好的整理一下,今天再翻一遍發現好多知識點和筆記都不懂了,果然不能再拖了,應該學完就彙總成筆記的。
首先回顧一下條款10和條款21的內容吧。
書上的**如下:
class widget
...};
①operator=的引數為什麼要求const和&?
a:賦值運算子過載函式的引數是函式所在類的const型別的引用,加上const是為了不修改原值,加上&是為了直接使用實參,避免拷貝提高效率。
②為什麼賦值操作需要返回乙個reference指向左側實參?
a:在**中,this是呼叫該函式(在此處即為operator=)的物件的位址,*this即代表當前的物件。這裡的問題其實可以分解成兩個,第乙個問題是為什麼需要有返回值,賦值操作符沒有返回值行不行?第二個問題是返回值為什麼需要是引用,返回值型別行不行?
對於第乙個問題,答案是為了實現連續賦值。例如a=b=c;這樣的語句,如果是void沒有返回值,那麼處理完b.operator=(c)之後,沒有返回值給a.operator=(),這樣就實現不了連續賦值了。
對於第二個問題,答案是為了應對(a=b)=c;這種情況,這裡打破了從右往左賦值的順序,首先運算a=b,由於返回的是乙個值型別而不是乙個引用,編譯器會對返回的物件進行一次拷貝,得到乙個臨時的副本,按c++規定來說這個副本是乙個右值,接下來進行=c的操作,副本作為右值出現在等號左邊,自然是不行的。返回引用也有個效果,
總的來說問題①②只在特定問題下出問題,並不是強制要求解決的,但是為了保證過載後的運算子盡量保留原特性,最好還是這麼做。原賦值運算子=能做到a=b=c和(a=b)=c,不能過載後就做不到對不對?
書上**如下:
const
rational& operator*(const
rational
lhs, const
rational& rhs)
這裡過載了乘法操作符,用於進行有理數的乘法,分子分母分別相乘。此處在stack空間建立了乙個local物件(區域性物件)result,為了避免呼叫建構函式,函式返回乙個引用指向result,而不是值型別。
可以容易的看出這個函式存在的題,因為函式內部定義的變數result是個local變數,而local物件在函式退出前被銷毀了,因此返回的引用是是乙個「殘骸」,這很明顯會造成問題。事情的真相是,任何函式如果返回乙個reference指向某個local物件,都將一敗塗地。
實際上條款21不僅**了on the stack(棧區)的情況,也討論的on the heap的情況,和本文關係不大就不贅述了。
第一次閱讀條款21的時候,馬上就翻回條款10,因為同樣是運算子過載,為什麼operator=最好是返回引用,而operator*則不返回?
分析了一下還是因為賦值操作符的特殊性,operator=過載只能是成員函式,而且函式體中有return *this,即當前呼叫函式的物件已經存在,而不是臨時構建的local物件,自然不會出現第二部分的情況。
使用引用作為返回值可以減少開銷,實現連續賦值,但是也並不是什麼情況下都能使用引用的,那麼問題來了,究竟什麼時候使用引用?已經有大神為我們總結好了:
c++中引用(&)的用法和應用例項
摘錄一段:
流操作符《和》、賦值操作符=的返回值、拷貝建構函式的引數、賦值操作符=的引數需要使用引用,再囉嗦一下,其中拷貝建構函式的引數必須是引用,而不是「推薦使用引用」,至於原因可以參考拷貝建構函式的引數型別必須是引用。在另外的一些操作符中,卻千萬不能返回引用:+-*/ 四則運算符。它們不能返回引用
總結下來是並不能無腦使用reference來提高效率,很多地方需要思考一下,就像條款21末尾作者總結的那樣:當你必須在「返回乙個reference和返回乙個object」之間抉擇時,你的工作就是挑出行為正確的那個。
effective C 讀書筆記 條款10
條款10 令operator 返回乙個reference to this 關於賦值,我們可以這樣寫 int x,y,x x y z 這就是所謂的連續賦值 為了實現 連鎖賦值 賦值操作符必須返回乙個reference指向操作符的左側實參。這是我們為class實現賦值操作符時應該遵循的協議 includ...
Effective C 經驗條款
高效c 4 必須返回物件時,別妄想返回其reference 這句話什麼意思呢?就是在乙個函式內,如果你需要這個函式返回乙個新的物件,那麼這個函式的返回值型別就不要定義成引用型別。就直接返回這個類型別。首先,我們知道在函式傳遞引數時,傳遞引用的好處,尤其是對那麼比較大的型別,但是對於內建型別和stl的...
effective c 條款總結
條款1 盡量用const 和inline 而不用 define 條款2 盡量用而不用 條款3 盡量用new delete 而不用malloc free 條款4 盡量使用c 風格注釋 條款5 對應的new和delete 都要採用相同的形式 條款6 析構函式裡對指標成員呼叫delete條款 條款7 預先...