Effective C++ 之學習:from 條款21 to ...

條款21:Don't try to return a reference when you must return an object

觀點一:在使用引用的時候必須明確該引用指向誰,引用是常指針實現的,故而其所指向的對象肯定是唯一不可變的,所以在使用引用的時候必須明確其指向。

觀點二:函數應該儘可能的避免返回一個指向局部對象的指針或者引用。因爲局部對象在函數體執行完之後就會被銷燬,這時候,指針和引用就找不到其指向的對象,就會出現嚴重錯誤。即便是返回建立在堆上的對象,因爲在返回該對象的引用之後,無法真正獲取其背後的指針,也就無法delete所new的對象,出現內存泄漏。(堆中的變量不會自動解析?)

eg:

const A& operator*(const A& lhs,const A& rhs)
{
  A* res = new A(lhs.val*rhs.val)
  return *res;
}
A a1,a2,a3,a4;
a4 = a1*a2*a3;

調用兩次operator*,但是卻沒法刪除對應的對象(因爲函數體內部每次都會new一個對象來保存*的結果,無法刪除的是這個new的對象res,而不是a2,a3,a4)

條款22:declear data members private

其一:將成員變量聲明爲public,類的用戶就可以隨意更改之,而不用遵循某種類設計者的規則,這可能導致類的使用偏離於類的設計目的。比如說有一個類用來描述樹木,其屬性有直徑,高度等等,如果這些成員變量(屬性)能被隨意更改,那可能設計出一個直徑10,高1的樹對象,這很明顯不符合常理。

其二,private體現出封裝的好處,封裝之後,不能隨意接觸到類的成員變量,必須通過類設計者設計的public成員函數來訪問,這樣設計者可以在該成員函數中施加一定的約束,確保不會出現偏離類的設計目的。且不僅僅是約束,也可以使得類的實現更加彈性(可以提供很多個接口,以多種方式訪問某個成員變量,比如const和非const)。

其三,封裝之後,所有的訪問者都必須經過同一個或者同一批接口去訪問某個成員變量,那麼當這個成員變量改變的時候,也許只需要改變這個接口的實現就可以保證系統的正常運行,而不必重寫與該變量有關的所有代碼。比如設計一個檢測車輛實時速度的類,一開始類內有個變量a,記錄當前平均速度,成員函數返回該變量。當因爲內存限制,類刪去了這個變量,那麼修改接口函數,使其從收集器中獲取數據,來臨時計算平均速度並返回,就可以保證系統正常運行。或者反過來,本身沒有那個變量,但是後期類設計者爲了追求該系統的反應速度,添加了這個變量來記錄當前平均速度,此時也只需要讓接口函數直接返回該變量即可。

其四:protected封裝性也不好。

條款23:Prefer non-member, non-friend functions to member functions

non-member&non-friend 函數更加有利於封裝。(越間接越封裝?間接調用member functions)

從而更有利於大型程序的開發。由於類必須設計成一個整體,如果設計成member function OR friend function,後續編譯如果只需要一部分內容,還是包括整個文件,降低了效率。設計爲non-mem&non-friend可以在日後需要時,包含某些函數即可,不必包含整個類。

條款24:declear non-member function when type conversions should apply to all parameters

如果想讓類的隱式類型轉換髮生在函數的每一個參數身上,最好把這個函數設計成non-mem&non-friend。

書上說的比較拗口,不過通過一個例子就可以感受到。

比如我們設計了一個complex類,現在想讓complex類和int類之間作*運算且不用重新定義一個函數,而是直接用隱士轉換,使得int隱式轉換爲complex類,這時候如果設計成mem函數,其調用形式是固定的,必須要麼complex*int,要麼complex.operator*(int),也就是int必須位於參數列表,位於complex之後,這明顯不符合懲罰交換律。

不設計成friend函數的原因說的比較玄乎,friend帶來的麻煩一般遠大於其帶來的便利,故而能不設計成friend就不涉及。

條款25沒懂。。

條款26:postpone variable definitions as long as possible

就是將變量的定義儘量延後,最好的情況是在剛好要用到它之前定義,並儘可能用一個有意義的值去初始化它,這樣可以防止在定義之後出現異常,然後整個程序都沒用過這個變量,但是依然要承擔定義這個變量的成本,包括析構,構造。避免使用default是避免出現無意義的賦值,提高程序的清晰度。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章