天天看點

Effective C++ 讀書筆記之Part1.Accustoming Yourself to C++

1、View C++ as a federation of languages

C++的四個次語言:

1)C

2)Object-Oriented C++

3)Template C++

4)STL

2、Prefer consts, enums, and inlines to #defines

一方面是因為使用宏定義不利于調試的時候定位錯誤,另一方面主要是因為預處理器和編譯器兩者分工不同所導緻的。

同時,宏定義太複雜的情況下很容易出現錯誤。

總結:

第一,對于單純常量,最好以const對象或enums替換#defines.

第二,對于形似函數的宏(macros),最好改用inline函數替換#defines。

3、Use const whenever possible

const 文法雖然變化多端,但并不莫測高深。如果關鍵字const 出現在星号左

邊,表示被指物是常量:如果出現在星号右邊,表示指針自身是常量:如果出現在

星号兩邊,表示被指物和指針兩者都是常量。

char greeting[] = "Hello";

char * p = greeting;                      //non-const pointer, non-const data

const char* p = greeting;             //non-const pointer, const data

char* const p = greeting;             //const pointer, non-const data

const char* const p = greeting;  //const pointer, const data

如果被指物是常量,有些程式員會将關鍵字const 寫在類型之前,有些人會把

它寫在類型之後、星号之前。兩種寫法的意義相同,是以下列兩個函數接受的參數

類型是一樣的:

void f1(const Widget* pw);

void f2(Widget const * pw);

兩種形式都有人用,你應該試着習慣它們。

STL 選代器系以指針為根據塑模出來,是以疊代器的作用就像個?指針。聲

明選代器為 const 就像聲明指針為 const 一樣(即聲明一個T* const 指針) ,表

示這個疊代器不得指向不同的東西,但它所指的東西的值是可以改動的。如果你希

望疊代器所指的東西不可被改動(即希望STL 模拟一個 const T* 指針) ,你需要

的是 const _iterator:

std::vector<int> vec;

const std::vector<int>::iterator iter = vec.begin( );  //iter的作用就像個T* const

* iter = 10;                                                                    //沒有問題,改變iter所指物

++iter;                                                                           //錯誤,iter是const

std: :vector<int>::const iterator clter = vec.begin( );   //cIter的作用像是個const T *

*clter = 10;                                                                       //錯誤,*cIter是const

++clter;                                                                             //沒問題 

第一,某些東西聲明為const 可幫助編譯器偵測出錯誤用法。const 可被施加于任何作用域内的對象、函數參數、函數傳回類型、成員函數本體。

第二,編譯器強制實施 bitwise constness ,但你編寫程式時應該使用"概念上的常量性"

(conceptual constness)。

第三,當 const 和 non-const 成員函數有着實質等價的實作時,令 non-const 版本調

用 const 版本可避免代碼重複。

4、Make sure that objects are initialized before they're used

     所謂 static 對象,其壽命從被構造出來直到程式結束為止,是以 stack 和heap-based 對象都被排除。這種對象包括 global 對象、定義于 namespace 作用域内的對象、在 classes 内、在函數内、以及在 file 作用域内被聲明為 static 的對象。函數内的 static 對象稱為 local static 對象(因為它們對函數而言是 local) ,其他 static對象稱為 non-local static 對象。程式結束時 static 對象會被自動銷毀,也就是它們的析構函數會在main

()結束時被自動調用。

        所謂編譯單元<translation unit)是指産出單一目标檔案 (singleobject file) 的那些源碼。基本上它是單一源碼檔案加上其所含入的頭檔案(#include files) 。

第一,内置型對象進行手工初始化,因為 C++不保證初始化它們。

第二,構造函數最好使用成員初值列 (member initialization list) ,而不要在構造函數本體内使用指派操作(assignment) 。初值列列出的成員變量,其排列次序應該和它們在 class 中的聲明次序相同。

第三,為免除"跨編譯單元之初始化次序"問題,請以local static 對象替換 non-local static 對象。

感悟:

從這部分的内容大緻可以看出整本書的風格,主要是在多種可以實作的情況下告訴你哪種情況更加合适,更加可以避免錯誤。進而讓讀者的水準從對C++的一般了解進入到更深的層次。所列的點都是平時容易遇到的。必須要有一定的C++實踐經驗才讀出效果,否則看完了也記不住。跟實踐經驗很少的人直接去讀設計模式是一個效果。