强制类型转换形式:
cast-name<type>(expression)
一、static_cast
任何具有明确定义的类型转换,只要不包含底层const,就可以使用static_cast。对于隐式类型可以转化的,就可以用此类型
二、const_cast
const_cast只能改变运算对象的底层const。理解成去掉const性质,这样编译器不再阻止我们对该对象的写操作。只能用于指针或者引用。
三、reinterpret_cast
隐式转换通不过的时候可以用这个。
```cpp
char *p;int *q;
p = reinterpret_cast<char*>(q);
int a[5]={1,2,3,4,5};
int *p = reinterpret_cast<int*>((reinterpret_cast<int>(a)+1));
四、dynamic_cast
用于动态类型转换。需要用于含有虚函数的类。转换目标只能转指针和引用,转指针时失败则结果为0,对于引用则抛出bad_cast异常
#include <iostream>
#include <string>
using namespace std;
class Base1
{
public:
virtual void print1()
{
cout<<"Bas1 B"<<endl;
}
};
class Derived1 :public Base1
{
public:
virtual void print1(){
cout<<"Derived D"<<endl;
}
};
int main(int argc, char *argv[])
{
//对于static_cast和const_cast的使用练习
/*
int i;
double d;
const string *ps ;
char * pc;
void *pv;
pv=static_cast<void*>(const_cast<string *>(ps));
//i=int(*pc);
i=static_cast<int>(*pc);
//pv=&d;
pv=static_cast<void *>(&d);
//pc=(char*)pv;
pc=static_cast<char *>(pv);
*/
//对于动态转换的使用,指针类型,将基类转换成派生类
//
Base1* bp1=new Base1;
Derived1 *dp1 =dynamic_cast<Derived1*>(bp1);
//指针类型转换失败则为0
if(dp1)
{
cout<<"第一次派生转换基类指针成功"<<endl;
dp1->print1();
}
else
cout<<"第一次转换失败"<<endl;
//上边转换出错,需要new的时候new一个派生类大小
Base1* bp2=new Derived1;
Derived1 *dp2 =dynamic_cast<Derived1*>(bp2);
//指针类型转换失败则为0
if(dp2)
{
cout<<"第二次派生转换基类指针成功"<<endl;
dp2->print1();
}
else
cout<<"第二次转换失败"<<endl;
//第三次,将派生类转换成基类
Derived1 * dp3=new Derived1;
Base1 * bp3 = dynamic_cast<Base1*>(dp3);
if(bp3)
{
cout<<"第三次转换"<<endl;
bp3->print1();
}
else
cout<<"第三次转换失败"<<endl;
return 0;
}
第一次转换失败
第二次派生转换基类指针成功
Derived D
第三次转换
Derived D
总结
一般情况用static_cast,脱常用const_cast,处理不了的用 reinterpret_cast,碰到虚函数多态时用dynamic_cast。
define宏在预处理的时候发生替换,const是在编译过程中发生替换,而虚函数是动态绑定机制,在运行的时候编译器根据对象的动态类型自动选择正确的函数版本。