C风格的强制类型转换很简单,均用 Type b = (Type)a 形式转换。C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用,如下表:
转换类型操作符 | 作用 |
---|---|
const_cast | 去掉类型的const或volatile属性 |
static_cast | 无条件转换,静态类型转换 |
dynamic_cast | 有条件转换,动态类型转换,运行时检查类型安全(转换失败返回NULL) |
reinterpret_cast | 仅重新解释类型,但没有进行二进制的转换 |
1、const_cast
用于移除类型的const、volatile和__unaligned属性。
常量指针被转换成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然引用原来的对象。
const char *pc;
char *p = const_cast<char*>(pc);
2、static_cast
类似C风格的强制转换,进行无条件转换,静态类型转换,这几种写法都是等效的。
例:int(z), (int)z, static_cast
3、dynamic_cast
有条件转换,动态类型转换,运行时检查类型安全(转换失败返回NULL):
1)安全的基类和子类之间的转换。
2)必须有虚函数。
3)相同基类不同子类之间的交叉转换,但结果返回NULL。
class Base {
public:
int _i;
virtual void foo() {}; //基类必须有虚函数。保持多态特性才能使用dynamic_cast
};
class Sub : public Base {
public:
char *_name[100];
void Bar() {};
};
int main() {
Base* pb = new Sub();
Sub* ps1 = static_cast<Sub*>(pb); //子类->父类,静态类型转换,正确但不推荐
Sub* ps2 = dynamic_cast<Sub*>(pb); //子类->父类,动态类型转换,正确
Base* pb2 = new Base();
Sub* ps21 = static_cast<Sub*>(pb2); //父类->子类,静态类型转换,危险!访问子类_name成员越界
Sub* ps22 = dynamic_cast<Sub*>(pb2);//父类->子类,动态类型转换,安全,但结果为NULL
return 0;
}
4、reinterpret_cast
非常激进的指针类型转换,在编译期完成,可以转换任何类型的指针,所以极不安全。非极端情况不要使用。
格式:
reinterpret_cast<type>(expression)
例如:
int *ip;
char *pc = reinterpret_cast<char*>(ip);