## 規范類型轉換
* xxx_cast<轉換類型>(轉換參數),編譯器可以在編譯期間對類型轉換做更多的檢查,可以對一些不合理的轉換進行糾錯
#### static_cast
* 靜態的類型轉換,不通過運行時類型檢查來保證轉換的安全性。
* 只能用于轉化可以隱式轉化的類型,如基本類型之間的轉換,把派生類的指針或引用轉換成基類(上行轉換),把非const屬性的類型轉換為const,把void*的指針轉換成其他類型的指針
* 其他轉換是不安全的
#### dynamic_cast
* 能夠在運行時進行類型檢查,比 static_cast 更安全,但是耗更多的系統資源。
* dynamic_cast對于非法的下行轉換會返回空指針,可以在一定程度上避免不安全的類型轉換
* 只用于將派生類指針轉化為基類指針,否則會賦空值。這種轉化只能用于 is-a 類型的轉化
* `Base *pBase = dynamic_cast<Base*>(pSub);`
#### const_cast
#### reinterpret_cast
* reinterpret_cast 用于指針類型之間的轉換,它能對數據的比特位重新解釋轉換為我們需要轉換的對象
* reinterpret_cast 能處理所有指針(引用)之間的轉換,而static_cast只能處理有繼承關系類的指針和內置數據類型的指針的轉換
## 繼承構造函數
* 傳統C++中的繼承體系中,需在構造函數中顯式調用基類的構造函數,才能適用基類的構造函數
```c++
struct A
{
A(int i) {}
A(double d, int i) {}
A(float f, int i, const char* c) {}
};
struct B : A
{
B(int i) : A(i) {}
B(double d, int i) : A(d,i) {}
B(float f, int i, const char* c) : A(f,i,c) {}
//注:此處是可以接著寫對本類中成員變量的初始化列表,如 B(float f, int i, const char* c) : A(f,i,c), d(1) {}
};
```
* 上述寫法非常累贅,C++11中可以通過一個using聲明來解決這個問題
```c++
struct A
{
A(int i) {}
A(double d, int i) {}
A(float f, int i, const char*c) {}
};
struct B : A
{
using A::A; //等價于上述寫法
};
```
* 使用using語句來繼承構造函數時,派生類無法對類自身定義的成員變量進行初始化,此時可使用類成員的初始化表達式,給成員變量一個默認值
```c++
struct B : A
{
using A::A;
int d{0}; //注:C++的成員變量不允許使用 int d = 0; 這種方式來初始化
}
```
* 使用using語句是隱式聲明繼承的,即如果一個繼承構造函數不被使用,編譯器不會為其產生相關代碼
* 其他問題:參數默認值不會被繼承;多個基類的構造函數沖突(可顯式定義相關構造函數來指定繼承規則);一旦還用繼承構造,編譯器就不會為派生類生成默認構造函數
## 委派構造函數