C/C++中的四种强制类型转换。
c中的强制类型转换
显式转换:
TYPE b = (TYPE) a;
隐式转换:
floag b=0.5;
int b=a; //向零取整
C++中兼容了C中的用法,并提供了4个强制转换类型关键字:
static_cast
const_cast
reinterpret_cast
dynamic_cast
1)static_cast
用法:
static_cast<type_id>(expression)
该关键字把expression的类型转换为type_id的类型,但没有运行时类型检查来保证转换的安全性。
主要用法:
(1)用于类层次结构中基类和子类之间指针或引用的转换。
上行转换:把一个(expression)从派生类转换为基类(安全)
下行转换:把一个(expression)从基类转换为炮声类(没有动态类型检查,不安全)
(2)用于基本数据类型的转换,int->char int->enum
(3)把空指针转换为目标类型的指针
(4)把任何类型表达式转换为void类型。
const auto a1=11;
const auto a2=4;
//C style
double res1=(double)(a1) / (double)(a2);
//c++ style
auto res2 = static_cast<double>(a1) / static_cast<double>(a2);
static_cast 不能转换掉const volitale关键字修饰的变量。
const int a=11;
const int *p;
const auto *res1 = static_cast<const int *>(p); //right
int *res2=static_cast<int *>(p); //error
- const_cast
弥补1)static中不能转换const、volitale的不足,const_cast可以。
用法:
const_cast<type_i>(expression)
const int a=10;
const int *p=&a;
*p=20; //error
int res1 = const_cast<int>(a); //error
int res2 = const_cast<int *>(p);//right
//<>中必须是引用或指针,不能是实际变量
3)reinterpret_cast
用途:
1、改变指针或引用类型
2、将指针或引用转换为一个足够长度的整形。
3、将整形转换为指针或引用类型
用法:
reinterpret <type_id> (expression)
- dynamic_cast
特点:
1、上面三种都是在编译时完成的,dynamic_cast是在运行时完成的,运行时要进行类型检查
2、不能用于基本数据类型的转换
3、要求<>内的目标必须为指针或者引用。转换成功返回对应类型的指针,否则返回nullptr。
4)上行转换时跟static_cast效果一样,下行转换时进行类型检查,比static_cast安全。
5)使用dynamic_cast进行转换,基类中一定要有虚函数否则无法编译通过。由于运行时类型检查需要运行时类型信息,储存在类中的虚函数表中,因此必须定义了虚函数的类才有意义。
class A {
public:
virtual void print(){
cout << "in class A" << endl;
};
};
class B :public A {
public:
void print(){
cout << "in class B" << endl;
};
};
class C {
void pp(){
return;
}
};
int main() {
A *a1 = new B; // a1是A类型的指针指向一个B类型的对象
A *a2 = new A; // a2是A类型的指针指向一个A类型的对象
B *b1, *b2, *b3, *b4;
C *c1, c2;
b1 = dynamic_cast<B*>(a1); // not null,向下转换成功,a1 之前指向的就是 B 类型的对象,所以可以转换成 B 类型的指针。
if (b1 == nullptr) cout << "b1 is null" << endl;
else cout << "b1 is not null" << endl;
b2 = dynamic_cast<B*>(a2); // null,向下转换失败
if (b2 == nullptr) cout << "b2 is null" << endl;
else cout << "b2 is not null" << endl;
// 用 static_cast,Resharper C++ 会提示修改为 dynamic_cast
b3 = static_cast<B*>(a1); // not null
if (b3 == nullptr) cout << "b3 is null" << endl;
else cout << "b3 is not null" << endl;
b4 = static_cast<B*>(a2); // not null
if (b4 == nullptr) cout << "b4 is null" << endl;
else cout << "b4 is not null" << endl;
a1->print(); // in class B
a2->print(); // in class A
b1->print(); // in class B
// b2->print(); // null 引发异常
b3->print(); // in class B
b4->print(); // in class A
c1 = dynamic_cast<C*>(a1); // 结果为null,向下转换失败
if (c1 == nullptr) cout << "c1 is null" << endl;
else cout << "c1 is not null" << endl;
// c2 = static_cast<C*>(a1); // 类型转换无效, Cannot cast from 'A*' to 'C*' via static_cast
// delete 省略
}