1. 程式人生 > >《Effective C++》讀書筆記:(一)讓自己習慣C++

《Effective C++》讀書筆記:(一)讓自己習慣C++

條款01:四個次語言:C、Object-Oriented C++、Template C++(泛型和模板超程式設計)、STL

 條款02:用inline、enum、const代替#define

#define定義的巨集,複雜起來,就會很難理解。

(1)對於單純常量,最好以const物件代替#defines。

class CostEstimate{
private:
	static const double FudgeFactor;  //常量聲名,放在標頭檔案
	...
};
const double CostEstimate::FudgeFactor=1.35; //常量定義,放在實現檔案內

(2)“the enum hack”補償做法,解決編譯期間class需要一個class常量

class GamePlayer{
  private:
	enum{ NumTurns=5 };   //使NumTurns成為5的記號
    int scores[NumTurns];
    ...
};

(3)對於形似函式的巨集,用inline函式替代#define。

條款03:儘可能使用const

(1)不需要進行改變的資料加上const字首。包括指標、迭代器、指標迭代器及reference指代的物件、函式引數、返回型別、lacal變數、成員函式前。

(2)指標的const字首有兩種形式,const放在*左邊表示資料不變,放右邊表示指標地址不變。

(3)迭代器由指標塑模。區分const迭代器的兩種情況:

const std::vector<int>::iterator iter=vec.begin();    // T* const  不可改變指標值
std::vector<int>::const_iterator cIter=vec.begin();   //const T*   不可改變物件值

(4)不改變的函式返回值加const。如過載運算子函式,可讓“a*b==c”寫成“a*b=c”的打字錯誤在編譯時報錯。

(5)返回不需要修改的成員資料的成員函式需要加上const標記。編譯器強制實施bitwise constness,但編寫程式時應該使用“概念上的常量性”。

既編譯器認為const成員函式不可以更改物件內任何non-static成員變數。

(6)在const和成non-const成員函式中避免重複。當const和non-const成員函式有著實質等價的實現時,令non-cosnt版本呼叫const版本可避免程式碼重複。

class TextBlock{
public:
    ...
    const char& operator[](std::size_t position) const
    {
        ...
        ...                                            //這些是相同操作
        ...
        return text[position];
    }

    char& operation[](std::sizr_t position)
    {
        return const_cast<char&>                      //轉型二:為const op[]的返回值去掉const
               (ststic_cast<const TextBlock>(*this)   //轉型一:為*this加上const
                                       [position]) ;   
    }
    ...
};

條款04:使用物件前確保初始化。

(1)為內建型物件進行手工初始化,因為C++不保證初始化它們。

(2)確保每一個建構函式都將每一個成員初始化。構建函式最好使用成員初值列(member initialization list),而不要在構建函式本體內使用賦值操作。初值列列出的成員變數,其排列次序應該和它們在class中的宣告次序相同。

(3)C++對“定義於不同的編譯單元內的non-local static物件”的初始化相對次序並無明確定義,為免除“跨編譯單元之初始化次序”問題,請以local static物件替換non-local static物件。這種reference-returning函式結構簡單:第一行定義並初始化一個local物件,第二行返回這個物件。

class FileSystem { ... };
FileSystem& tfs()            //這個函式用來替換tfs物件
{
	static FileSystem fs;    //定義並初始化local static物件
	return fs;              
}

class Directory { ... };
Directory::Directory(params)
{
	...
	std::size_t disks=tfs().numDisks();  //使用tfs物件
	...
}
Directory& tempDir()       //這個函式用來替換td物件
{
	static Directory td;   //定義並初始化local static物件
	return td;
}