天天看點

Effective C++ 5

 通過default構造函數出一個對象再對他指派比直接在構造時指定指派 差。

比如

string str("honey~");和

string str; str="honey~";效率就不一樣。

接下來講循環時的初始化,

class A;

for(int i=0;i<n;i++)  //n次構造,n次析構

{

   A a(**);

}

//綜上,下面的情況好。

轉型分為舊式轉型和新式轉型。

舊式轉型: (T) expression

新式轉型:

1.const_cast<T>(expression)  cast away the constness

将對象的常量性移除

2.dynamic_cast<T>(expression) safe downcasting

唯一不能用舊式轉型實作的轉型動作。不過可能耗費重大運作成本的動作。

3.reinterpret_cast <T>(expression) 低級轉型

例:int*->int

4.static_cast<T>(expression) 強迫隐式轉換。

例:non-const  -> const ,int->double

     pointer-to-base  ->pointer-to-derived

     void*  -> typed 指針

現在運用舊式轉型符的時機是調用explicit構造函數。

handle:reference,指針,疊代器。

函數不要傳回一個指向通路級别較低的成員函數。因為會降低封裝性。

成語函數傳回對象内部的handle可能會使dangling。

下面來看異常:

異常安全函數保證:

1.基本承諾:異常不出錯即可能出于任何合法狀态。

2.強烈保證:異常傳回前一狀态。

3.不投擲保證:不跑出異常。

如int f() throw();   //不是說不抛出異常,而是隻要抛出異常,就導緻嚴重錯誤。

動态配置設定不成功就 bad_alloc異常。

如果一個系統中有一個函數不具備異常安全性,則整個系統不具備異常安全性。

封裝,異常安全性。

inline函數

1.免除調用成本

2.如果函數體過大,則會換頁行為和降低指令高速緩存裝置的擊中率。

3.對比函數本體和函數調用所産生的代碼長度。

4.因為inlining是編譯期行為,是以要在頭檔案中。

5.template通常也 是inline但不全是。

//此執行個體為了證明構造函數和析構函數最好不要inline

class Base

{

public:

...

private:

string bm1,bm2;

};

class Derived

{

public:

Derived(){} //看起來是空的。

private:

stirng dm1,dm2,dm3;

};

Derived::Derived()

{

Base::Base();

try{dm1.string::string();}

catch(...)

{

Base::~Base();

throw;

}

try{dm2.string::string();}

catch(...)

{

dm1.string::~string();

Base::~Base();

throw;

}

try{dm3.std::string::string();}

catch(...)

{

dm2.string::~string();

dm1.string::~string();

Base::~Base();

throw;

}

}

pimpl idiom 将實作放入一個類,在接口類中定義一個智能指針指向實作類,進而達到與實作細目分離。