要说的三个类型转换运算符其实都基于隐式转换。
隐式转换
cpp中存在无需显示指定转换就能成功赋值的实现。如:
//以下是合法行为
float b=3.0;
int i=b;
b=i;
静态类型转换——static_cast
语法格式: static_cast<目标类型> (标识符)
转化规则: 在一个方向上可以作隐式转换,在另外一个方向上就可以作静态转换。(当然双向可隐式转换也可以静态转换)
void *p;
int *q;
p=q;//合法,任何类型指针都可以赋值给void *
q=p;//错误,无法将void*赋值给int *
void* p;
int* q=new int(10);
p = q;
q = static_cast<int*>(p);//将void *强制转换为int*
return 0;
重解释类型转换reinterpret_cast
语法格式: reinterpret_cast<目标类型> (标识符)
转化规则 :“通常为操作数的位模式提供较低层的重新解释”也就是说将数据以二进制存在形式 的重新解释,在双方向上都不可以隐式类型转换的,则需要重解释类型转换。
int x = 0x12345648;
char*p=&x//不合法
char* p = reinterpret_cast<char*>(&x); //合法
脱常类型转换const_cast
语法格式: const_cast<目标类型> (标识符) //目标类类型只能是指针或引用。
语法规则: 用来移除对象的常量性(castaway the constness)使用 const_cast 去除const限定的目的不是为了修改它的内容,使用const_cast 去除const 限定,通常是为了函数能够接受这个实际参数。
实例:
void show(int & i)
{
cout<<i<<endl;
}
int main(void) {
const int m = 12345;
show(m);//不合法
show(const_cast<int&>(m));//合法,m脱常后可以传值给int &
return 0;
}
需要注意的是,无论何时都不要试图去修改const常量的值。
const int x = 200;
int& a = const_cast<int&>(x); // int &a = x;
a = 300;
cout<<a<<" "<<x<<endl;
cout<<&a<<"---"<<&x<<endl;
你会发现同一个地址居然有两个值。其实这是一种未定义的行为,如果换个编译器可能就无法运行了。
struct A { int data; };
const A xx = { 1111 };
A& a1 = const_cast<A&>(xx);
a1.data = 222;
cout << a1.data << xx.data << endl;
A* p1 = const_cast<A*>(&xx);
p1->data = 333;
cout << p1->data << xx.data << endl;
return 0;
在这里呢,可以改变 const 自定义类的成员变量(但这是不对的行为)。
RTTI类型判断dynamic_cast
dynamic_cast 一种运行时的类型转化方式,所以要在运行时作转换判断。检查指针所指类型,然后判断这一类型是否与正在转换成的类型有一种 “is a”的关系,如果是,dynamic_cast 返回对象地址。如果不是,dynamic_cast 返回 NULL。dynamic_cast 常用多态继承中,判断父类指针的真实指向。