Effective C++ 讀書筆記(18-28):類與函數之設計和聲明

來源:互聯網
上載者:User

類與函數的設計和聲明

看看作者思考問題的角度:

對象如何產生和銷毀: 構造析構、new和delete的重載

對象的初始化和賦值:構造、拷貝構造、賦值重載

新型別轉換相關:合法值的規範檢驗、繼承體系、是否隱式轉換

存取權限:public、protected、private如何設計

 

Item18 -- 努力讓介面完滿且最小化

1,KISS原則;2,標頭檔的重要性;

 

Item19 -- 區分member functions, non-member functions和friend functions三者

1,如果要實現虛函數,必須是member function
2,讓operator<<和operator>>成為non-members,如果還需要擷取類的非公用成員變數,聲明為friend。原因,如果是func為member,那麼以後書寫順序應該是obj>>cin,obj<<cout,這樣不符合習慣
3,只有non-member才能在最左參數身上實施型別轉換。如果需要對函數f的最左側參數進行型別轉換,那麼f為non-function,如果還需要擷取類的非公用成員變數,聲明為frind。
舉例,operator *(Class &lhs, Class &rhs)這種聲明,2*obj2的調用,需要對2進行型別轉換(建構函式聲明為explicit可以阻止隱式型別轉換),這樣就必須為non-member

Item20 -- 避免將data members放在公開介面中

Effective中舉了三個原因,說明為什麼不要放在公開介面中

  1. 一致性,以後對類對象的所有操作,均需要帶(),也就是只能調用函數,不能擷取變數
  2. 擷取控制性,比如唯讀、可讀可寫、不處理,通過不同的函數實現
  3. 函數抽象性,提供一個借口,底層如何?上層使用者不用關心

不過在實際編程中,很少人能夠完全做到這點,畢竟需要自己花些時間來寫get和set,暫時我也沒找到自動產生get、set函數的方法,所以魚與熊掌不可兼得,若想獲得好處,就得費力寫get、set了。

Item21 -- 儘可能使用const

1,*號在中間,前定內容後定針
2,傳回值用const修飾,說明傳回值是唯讀,不能修改
3,函數後面用const修飾,說明該函數不能修改任何變數。函數可以據此進行重載,有const的函數被const對象調用,沒有const的函數被非const對象調用
const的真正意義是什嗎?不變性,具體的體現有兩種說法:A, bitwise. B, conceptual,A說法對位進行比較,如果沒有修改則認為是不變的。B從概念層面進行判斷,即使底層有修改,但對上層概念來講是不變的,那就是不變的。但是C++語言只支援A,所以為了應付B,引入mutable修飾詞,用來修飾上層概念不變,但是底層要修改的底層變數。
4,const可以通過const_cast取消常量性

Item22 -- 盡量使用pass-by-reference,少用pass-by-value
  1. C語言裡面都是傳值
  2. 傳值成本比較大,會調用對象的拷貝構造,如果類比較複雜,則會建立和析構更多的對象
  3. 傳引用會避免切割問題。Func(base&) 和Func(base)兩種函式宣告,內部調用f()虛函數,如果傳遞個derived對象,則傳引用會調用derived.f(),而傳值則會切割而調用base.f()
Item23 -- 當你必須回傳object時,不要嘗試傳回reference

用重載乘法舉例

Inline const Rational Operator*( const Rational& lhs, const Rational & rhs)

{

return Rational(lhs.n*rhs.n, lhs.d*rhs.d);

}

傳回的是value,如果傳回reference的話,內部變數析構之後,引用沒有真正的對象

Item24 -- 在函數重載和參數預設化之間,謹慎選擇

void g(int x=0);

g();

g(10);

void f(); void f(int x);

f();

f(10);

兩種方式要謹慎選擇,避免出現模稜兩可的情況

Item25 -- 避免對指標型別和數值型別進行重載

void f(int x);

void f(string *ps);

f(0)

0的存在會對指標和數值造成模稜兩可,所以要堅決避免針對指標和數值進行重載

Item26 -- 防衛潛伏的ambiguity(模稜兩可)狀態

C++有一個哲學信仰,它相信潛在的模稜兩可狀態不是一種錯誤,但是對程式員來講,將所有問題放到運行後發現就是一種災難。所以程式員應該避免模稜兩可。
類的轉換,一是拷貝構造方式可以隱式轉換,一是operator Class()方式,當需要型別轉換時,就會有模稜兩可

  1. 語言標準轉換,6.02可以轉換成int也可以轉換成char
  2. 多繼承也是如此

當遇到模稜兩可情況時,程式員應該顯式的說明採用哪種方式。

Item27 -- 如果不想使用編譯器暗自產生的member functions,就應該明白拒絕它
  1. 使用private修飾防止公開調用
  2. 不定義防止friend等調用

private:

Array& operator=(const Array &rhs);(注意這裡;表示不定義)

 

Item28 -- 嘗試切割global namespace

namespace name1{

}

using namespace name1;

最好每個人都以自己姓名為name,進行分割,這樣可以類似Java中的包的概念

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.