1. 程式人生 > >Effective C++ 摘要(一)

Effective C++ 摘要(一)

1. 當你看到賦值符號“=”時,一定要小心, 因為賦值操作也可以呼叫copy建構函式:

    Widget w1;
    Widget w2 = w1;        //呼叫copy建構函式。
    Widget w3, w4;
    w3 = w4                //呼叫賦值操作符。
    copy 建構函式和copy賦值函式的區別是, 如果一個新物件被定義, 一定有個建構函式被呼叫,如果沒有新物件被定義, 就不會有建構函式呼叫。
 

2. In-class 初值設定只允許對整數常量進行, 如果你的編譯器不支援上述語法, 你可以將初值放在定義式:

    class CostE
    {
        private:
            static const double dFactor;        //static class 常量宣告位於標頭檔案內
    };
    
    const double CostE::dFactor = 1.11;            // 位於實現檔案內
    
    萬一編譯器不允許“static 整型class常量”進行 “in-class”初值設定, 可改用所謂的“the enum hack”補償方法。
    class GamePalyer
    {
        private:
            enum {NumTurns = 5};
            int scores[NumTurns];
    };
 

3. 巨集定義的錯誤

     #define MAX(a, b) f((a) > (b)? (a) : (b))

    int a = 5, b = 0;
    MAX(++a, b);        //a被累加兩次
    MAx(++a, b+10);        //a被累加一次
    

4.  const ×

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

    char* const p = strA;        //const pointer, non-const data
    const char* cosnt p  = strA;//cosnt pointer, const data
    const 出現在星號左側, 表示被指物是常量; 如果出現在星號右側, 表示指標是常量; 如果出現在星號兩側, 表示被指物和指標兩邊都是常量。
    const char* p  和 char const * p 是等價的。
 

5. const_iterator 就像 const T*, 迭代器所指的東西不可被改動。

 

6.  令函式返回一個常量值, 可以降低因客戶錯誤而造成的意外, 而又不放棄安全性和高效性。

    const Rational operator* (const Rational& lhs, const Rational& rhs);
    返回一個const物件的好處時, 如果客戶把== 誤寫成=,那麼編譯錯誤。
    Rational a, b, c;
    ...
    if (a*b = c)
 

    7.    const 成員函式, 形式為 void func1()const, 其作用是確認該成員函式可用於const物件身上。  

    class A
    {
        ...
        void func1();
        void func2() const;
        ...
    }
    
    const A objA;
    A objB;
    objA.func1();    //非法, 因為func1是非const成員函式, 不能用於const物件。
    objA.func2();    //合法, 只有const物件可以用於const函式。

    objB.func2();    //合法, 非const物件也可以呼叫const函式

8. const成員函式中如果確實要修改成員變數, 則定義成員變數為mutable。

 

9. override operator [] 下標過載    

    1) [] 只能通過成員函式過載.
    2) [] 返回型別為reference, 如果是值, 不能修改元素。
    3) [] 應該過載const成員函式版本和non-const成員函式版本, 以支援const物件的讀值操作。
    

10.   初始化列表

    1)C++規定, 物件的成員變數初始化發生在進去建構函式本體之前, 因此,建構函式中的成員變數賦值都是賦值操作,而非初始化。

    2)建構函式的最佳寫法是使用所謂的 member intialization list(成員初始化列)替換賦值操作。 成員初始化列效率更高。 因為通過賦值構造, 首先使用default建構函式為成員變數設初值, 然後再對它賦予新值。成員初始化列的做法避免了這一問題。

    3)const 成員變數或reference,他們一定需要初值, 不能被賦值,。 必須使用初始化列。

11. 成員初始化次序: base 早於 derived, 成員變數總是以器宣告次序被初始化。為避免閱讀時迷惑, 在成員初始列中列各個成員時, 最好總是以宣告次序為次序。