Effective C++

純筆記,看多少記多少,不做討論。

第一章 讓自己習(xí)慣C++ ? ?Accustoming Yourself to C++


條款01:視C++為一個(gè)語(yǔ)言聯(lián)邦

View C++ as a federation of languages

C++高效編程守則視狀況而變化,取決于你使用C++的哪一部分。


條款02:盡量以const, enum, inline替換 #define

Prefer consts, enums, and inlines to #defines

對(duì)于單純常量,最好以const對(duì)象或enums替換#defines。

對(duì)于形似函數(shù)的宏(macros),最好改用inline函數(shù)替換#define


條款03:盡可能使用const

Use const whenever possible

將某些東西聲明為const可幫助編譯器偵測(cè)出錯(cuò)誤用法,const可被施加于任何作用域內(nèi)的對(duì)象、函數(shù)參數(shù)、函數(shù)返回類型、成員函數(shù)本體。

編譯器強(qiáng)制實(shí)施bitwise constness,但你編寫(xiě)程序時(shí),應(yīng)該使用“概念上的常量性”(conceptual constness).

當(dāng)const和non-const成員函數(shù)有著實(shí)質(zhì)等價(jià)的實(shí)現(xiàn)時(shí),令non-const版本調(diào)用const版本可避免代碼重復(fù)。


條款04:確定對(duì)象被使用前已先被初始化

Make sure that objects are initialized before they're used

為內(nèi)置型對(duì)象進(jìn)行手工初始化,因?yàn)镃++不保證初始化它們。

構(gòu)造函數(shù)最好使用成員初值列(member initialization list),而不要在構(gòu)造函數(shù)本體內(nèi)使用賦值操作(assignment)。初值列列出的成員變量,其排列次序應(yīng)該和它們?cè)赾lass中的聲明次序相同。

為免除“跨編譯單元之初始化次序”問(wèn)題,請(qǐng)以local static對(duì)象替換non-local static對(duì)象。

========================================

第二章 構(gòu)造/析構(gòu)/賦值運(yùn)算? ? Constructors, Destructors, and Assignment Operators

條款05:了解C++默默編寫(xiě)并調(diào)用哪些函數(shù)

Know what functions C++ silently writes and calls.

編譯器可以暗自為class創(chuàng)建default構(gòu)造函數(shù)、copy構(gòu)造函數(shù)、copy assignment操作符,以及析構(gòu)函數(shù)。


條款06:若不想使用編譯器自動(dòng)生成的函數(shù),就該明確拒絕

Explicitly disallow the use of compiler-generated functions you do not want

為駁回編譯器自動(dòng)(暗自)提供的機(jī)能,可將相應(yīng)的成員函數(shù)申明為private并且不予實(shí)現(xiàn)。使用像Uncopyable這樣的base class也是一種做法。


條款07:為多態(tài)基類申明virtual析構(gòu)函數(shù)

Declare destructors virtual in polymorphic base classes.

polymorphic(帶多態(tài)性質(zhì)的)base classes應(yīng)該聲明一個(gè)virtual析構(gòu)函數(shù)。如果class帶有任何virtual函數(shù),它就應(yīng)該擁有一個(gè)virtual析構(gòu)函數(shù)。

Classes的設(shè)計(jì)目的如果不是作為base classes使用,或不是為了具備多態(tài)性(polymorphically),就不應(yīng)該聲明virtual析構(gòu)函數(shù)。


條款08:別讓異常逃出析構(gòu)函數(shù)

Prevent exceptions from leaving destructors.

析構(gòu)函數(shù)絕對(duì)不要吐出異常。如果一個(gè)被析構(gòu)函數(shù)調(diào)用的函數(shù)可能拋出異常,析構(gòu)函數(shù)應(yīng)該捕捉任何異常,然后吞下它們(不傳播)或結(jié)束程序。

如果客戶需要對(duì)某個(gè)操作函數(shù)運(yùn)行期間拋出的異常做出反應(yīng),那么class應(yīng)該提供一個(gè)普通函數(shù)(而非在析構(gòu)函數(shù)中)執(zhí)行該操作。


條款09:絕不在構(gòu)造和析構(gòu)過(guò)程中調(diào)用virtual函數(shù)

Never call virtual functions during construction or destruction.

在構(gòu)造和析構(gòu)期間不要調(diào)用virtual函數(shù),因?yàn)檫@些類調(diào)用從不下降至derived class(比起當(dāng)前執(zhí)行構(gòu)造函數(shù)和析構(gòu)函數(shù)的那層)。


條款10:令operator=返回一個(gè)reference to *this

Have assignment operators return a reference to *this

令賦值(assignment)操作符返回一個(gè)reference to *this。


條款11:在operator=中處理“自我賦值”

Handle assignment to self in operator=.

確保黨對(duì)象自我賦值時(shí)operator=有良好的行為。其中技術(shù)包括比較“來(lái)源對(duì)象”和“目標(biāo)對(duì)象”的地址、精心周到的語(yǔ)句順序、以及copy-and-swap。

確定任何函數(shù)如果操作一個(gè)以上的對(duì)象,而其中多個(gè)對(duì)象是同一個(gè)對(duì)象時(shí),其行為仍然正確。


條款12:復(fù)制對(duì)象時(shí)勿忘其每一個(gè)成分

Copy all parts of an object

Copying函數(shù)應(yīng)該確保復(fù)制“對(duì)象內(nèi)的所有成員變量”及“所有base class成分”。

不要嘗試以某個(gè)copying函數(shù)實(shí)現(xiàn)另一個(gè)copying函數(shù)。應(yīng)該將共同機(jī)能放進(jìn)第三個(gè)函數(shù)中,并由兩個(gè)copying函數(shù)共同調(diào)用。

========================================

第三章 資源管理? ? Resource Management


條款13:以對(duì)象管理資源

Use objects to manage resources.

為防止資源泄露,請(qǐng)使用RAII(Resource Acquisition Is Initialization: RAII)對(duì)象,它們?cè)跇?gòu)造函數(shù)中獲得資源并在析構(gòu)函數(shù)中釋放資源。

兩個(gè)常被使用的RAII classes分別是tr1::shared_ptr和auto_ptr。前者通常是較佳選擇,因?yàn)槠鋍opy行為比較直觀。若選擇auto_ptr,復(fù)制動(dòng)作會(huì)使它(被復(fù)制物)指向null。


條款14:在資源管理類中小心copying行為

Think carefully about copying behavior in resource-managing classes.

復(fù)制RAII對(duì)象必須一并復(fù)制它所管理的資源,所以資源的copying行為決定RAII對(duì)象的copying行為。

普遍而常見(jiàn)的RAII class copying行為是:抑制copying行為、實(shí)施引用計(jì)數(shù)法(reference counting)。不過(guò)其他行為也都可能被實(shí)現(xiàn)。


條款15:在資源管理類中提供對(duì)原始資源的訪問(wèn)

Provide access to raw resources in resources-managing classes.

APIs往往要求訪問(wèn)原始資源(raw resources),所以每一個(gè)RAII classes應(yīng)該提供一個(gè)“取得其所管理之資源”的辦法。

對(duì)原始資源的訪問(wèn)可能經(jīng)由顯示轉(zhuǎn)換或隱式轉(zhuǎn)換。一般而言顯示轉(zhuǎn)換比較安全,但隱式轉(zhuǎn)換對(duì)客戶比較方便。


條款16:成對(duì)使用new和delete時(shí)要采取相同形式

Use the same form in corresponding uses of new and delete.

如果你在new表達(dá)式中使用[],必須在相應(yīng)的delete表達(dá)式中也使用[]。如果你在new表達(dá)式中不使用[],一定不要在相應(yīng)的delete表達(dá)式中使用[]。


條款17:以獨(dú)立語(yǔ)句將newed對(duì)象置入智能指針

Store newed objects in smart pointers in standalone statements.

//未完成閱讀章節(jié)

以獨(dú)立語(yǔ)句將newed對(duì)象存儲(chǔ)于(置入)智能指針內(nèi)。如果不這樣做,一旦異常被拋出,有可能導(dǎo)致難以察覺(jué)的資源泄露。


========================================


第四章 設(shè)計(jì)與聲明? ? Designs and Declarations


條款18:讓接口容易被正確使用,不易被誤用

Make interfaces easy to use correctly and hard to use incorrectly.

好的接口很容易被正確使用,不容易被誤用。你應(yīng)該在你的所有接口中努力達(dá)成這些性質(zhì)。

“促進(jìn)正確使用”的辦法包括接口的一致性,以及與內(nèi)置類型的行為兼容。

“阻止誤用”的辦法包括建立新類型、限制類型上的操作,束縛對(duì)象值,以及消除客戶的資源管理責(zé)任。

trl::shared_ptr支持定制型刪除器(custom deleter)。這可以防范DLL問(wèn)題,可被用來(lái)自動(dòng)解除互斥鎖(mutexes;見(jiàn)條款14)等等。


條款19:設(shè)計(jì)class猶如設(shè)計(jì)type

Treat class design as type design.

Class的設(shè)計(jì)就是type的設(shè)計(jì)。在定義一個(gè)新type之前,請(qǐng)確定你已經(jīng)考慮過(guò)本條款覆蓋的所有討論主題。

新type的對(duì)象應(yīng)該如何被創(chuàng)建和銷毀?

對(duì)象的初始化和對(duì)象的賦值應(yīng)該有什么樣的差別?

新type的對(duì)象如果被passed by value(以值傳遞)意味著什么?

什么是新type的“合法值”?

你的新type需要配合某個(gè)繼承圖系(inheritance graph)嗎?

你的新type需要什么樣的轉(zhuǎn)換?

什么樣的操作符和函數(shù)對(duì)此新type而言是合理的?

什么樣的標(biāo)準(zhǔn)函數(shù)應(yīng)該駁回?

誰(shuí)該取用新type的成員?

什么是新type的“未聲明接口”(undeclared interface)?

你的新type有多么一般化?

你真的需要一個(gè)新type嗎?


條款20:寧以pass-by-reference-to-const替換pass-by-value

Prefer pass-by-reference-to-const to pass-by-value

盡量以pass-by-reference-to-const替換pass-by-value。前者通常比較高效,并可避免切割問(wèn)題(slicing problem)。

以上規(guī)則并不適用于內(nèi)置類型,以及STL的迭代器和函數(shù)對(duì)象。對(duì)它們而言,pass-by-value往往比較適當(dāng)。


條款21:必須返回對(duì)象時(shí),別妄想返回其reference

Don't try to return a reference when you must return an object.

絕不要返回pointer或reference指向一個(gè)local stack對(duì)象,或返回reference指向一個(gè)heap-allocated對(duì)象,或返回pointer或reference指向一個(gè)local static對(duì)象而有可能同時(shí)需要多個(gè)這樣的對(duì)象。條款4已經(jīng)為“在單線程環(huán)境中合理返回reference指向一個(gè)local static對(duì)象”提供了一份設(shè)計(jì)實(shí)例。


條款22:將成員變量聲明為private

Declare data members private

切記將成員變量聲明為private。這可賦予客戶訪問(wèn)數(shù)據(jù)的一致性、可細(xì)微劃分訪問(wèn)控制、允諾約束條件獲得保證,并提供class作者以充分的實(shí)現(xiàn)彈性。

protected并不比public更具封裝性。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • PART0、前言 TOPIC運(yùn)用c++進(jìn)行高效編程 收獲了解c++如何行為為什么那樣行為如何運(yùn)用其行為形成優(yōu)勢(shì) P...
    rh_Jameson閱讀 3,697評(píng)論 2 30
  • 這本書(shū)屬于“想提高必看之書(shū)”,相見(jiàn)恨晚,建議所有C++程序員都看看,沒(méi)事也可以拿出來(lái)翻翻。大家也可以瀏覽下面的筆記...
    拉普拉斯妖kk閱讀 771評(píng)論 0 1
  • 2 構(gòu)造/析構(gòu)/賦值運(yùn)算(續(xù)) 條款09:絕不在構(gòu)造和析構(gòu)過(guò)程中調(diào)用 virtual 函數(shù) 如果執(zhí)行BuyTran...
    暗夜望月閱讀 411評(píng)論 0 0
  • 再讀高效c++,頗有收獲,現(xiàn)將高效c++中的經(jīng)典分享如下,希望對(duì)你有所幫助。 1、盡量以const \enum\i...
    橙小汁閱讀 1,312評(píng)論 0 1
  • 1. 讓自己習(xí)慣C++ 條款01:視C++為一個(gè)語(yǔ)言聯(lián)邦 為了更好的理解C++,我們將C++分解為四個(gè)主要次語(yǔ)言:...
    Mr希靈閱讀 2,996評(píng)論 0 13

友情鏈接更多精彩內(nèi)容