Effective C++總結

  1. explicit 可以用來阻止隱式類型轉化
  2. 如果類成員變量裏面存在const 或 引用數據成員,則拷貝賦值函數,即operator =,需要自己重寫,不可以用默認拷貝賦值;如果有成員變量有指針,視具體情況而定。
  3. 爲駁回編譯器默認的提供的機能,可將相應的成員函數聲明爲private並且不予實現。使用像Uncopyable這樣的base class也是一種做法
  4. 帶有多態性質的base class(即有一個或一個以上virtual 成員函數),應該聲明一個virtual 析構函數
  5. 析構函數絕對不要吐出異常,如果一個被析構函數調用的函數可能拋出異常,析構函數應該捕捉任何異常,然後吞下它們或結束程序
  6. 在構造和析構期間不要調用virtual函數,因爲這類調用從不下降至derived class
  7. 令賦值assignment操作符返回一個 reference to *this,這樣可以鏈式賦值
public:
    Widget & operator=(const Widget & rhs)
    {
        ...
        return *this;
    }

8.在operator = 中處理自我賦值,
方法一:這樣做每一次都需要判斷一次,降低了效率

Widget & operator =(const Widget &rhs)
{
    if( & rhs== this)return *this;
    delete pb;
    pb=new Bitmap(*rhs.pb);
    return *this;
    }

方法二:這樣效率最佳

Widget & operator =(const Widget &rhs)
{
    Bitmap *pOrig = & pb;//記住原來的pb
    pb=new Bitmap(*rhs.pb);
    delete pOrig;//刪除原來的pb
    return *this;
}

9.任何時候,只要你承擔起爲derived class撰寫copy函數的責任,你就要必須很小心的也複製其based class 成員變量,這些變量往往是private的,所以往往無法訪問,應該讓derived class 調用based class 的相應的函數,eg:

Derived::Derived(const Derived & rhs)
:Based( rhs ),//調用based class 的拷貝構造函數
priority( rhs.priority)
{
    log("copy");
}

Derived& Derived:: operator=(const Derived & rhs)
{
    Based::operator=(rhs);//對based 成分進行賦值操作
    priority=rhs.priority;
    return *this;
}
  1. 不要令copy assignment 操作符調用copy構造函數,也不要用copy構造函數調用 copy assignment 操作符,如果有重複代碼,應該提取到init函數共同使用

11.auto_ptr 智能指針與 shared_ptr 引用計數智能指針

auto_ptr指針所指對象擁有唯一擁有權

std:: auto_ptr<Investment> pInv1(creatInvestment());
std:: auto_ptr<Investment> pInv2(pInv1);//pInv2獲取對象,pInv1變爲null
pInv1=pInv2;//pInv1獲取對象,pInv2變爲null

shared_ptr可以多個指針同指一個對象,當沒有指針指向該對象時,對象的內存會自動釋放

void f()
{
    std::tr1::shared_ptr<Investment> pInv1(creatInvestment());//
    std::tr1::shared_ptr<Investment> pInv2(pInv1);//pInv1和pInv2指向同一對象
    pInv2=pInv1;//同上
}//pInv2,pInv1被銷燬,對象也被銷燬

12.以獨立指針將newd對象存入智能指針內。如果不這樣做,一旦異常被拋出,就會造成內存泄漏

13.儘量以pass-by-reference-to-const替代pass-by-value

14.絕不要返回一個pointer或reference指向一個local stack對象,或返回一個reference指向一個heap-allocated對象,或返回一個pointer或reference指向一個local static對象而有可能同時需要多個這樣的對象

15.如果你需要爲某個函數的所有參數(包括被this指針所指的那個隱喻參數)進行類型轉換,那麼這個函數必須是個non-member函數

class Rational
{
...
publicconst Rational operator *(const Rational &rhs)const;
    //這裏可以理解爲 *this * rhs
};
//假設result和onehalf是Rational類型
result = onehalf*2;//2會隱式轉換爲Rational,所以正常
result = 2*onehalf;//這裏錯誤,無法通過編譯

//如果換成以下函數定義,上面可以通過編譯
const Rational operator*(const Rational & lhs,const Rational & rhs)const;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章