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