💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
## 规范类型转换 * 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语句是隐式声明继承的,即如果一个继承构造函数不被使用,编译器不会为其产生相关代码 * 其他问题:参数默认值不会被继承;多个基类的构造函数冲突(可显式定义相关构造函数来指定继承规则);一旦还用继承构造,编译器就不会为派生类生成默认构造函数 ## 委派构造函数