## 规范类型转换
* 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语句是隐式声明继承的,即如果一个继承构造函数不被使用,编译器不会为其产生相关代码
* 其他问题:参数默认值不会被继承;多个基类的构造函数冲突(可显式定义相关构造函数来指定继承规则);一旦还用继承构造,编译器就不会为派生类生成默认构造函数
## 委派构造函数