有四个强制类型转换:static_cast 、reinterpret_cast 、 const_cast 、 dynamic_cast
static_cast 任何具有明确定义的类型转换,只要不包含底层 const ,都可以使用它。
int j = 3; float t = 3.14;
double u = static_cast<double >(j)/t; // 等价于 double u1 =(double) j/t;
把大的类型赋值给较小的类型时或者对于编译器无法自动执行的类型转换,static_cast非常有用。
double d=99;
void *p = &d;//任何非常量对象的地址都能存入 void* 中
double *d1 = static_cast<double *> (p);//将 void* 转换回初始的指针类型
const_cast:
它只能改变运算对象的底层 const。
const int * p;
int *p1 = const_cast<int *> (p);//这是正确的但是不能通过p1进行写值
将常量对象转换成非常量对象的行为,一般叫做 "去掉 const 性质 "。我去除了对象的 const 性质,编译器就不会阻止我们对该对象进行写操作了。但是对象本身是一个常量,利用上面强制转换后进行写操作会产生未定义的后果。
只有 const_cast 能改变表达式的常量属性,不能使用其他的。也不能使用它改变表达式的类型。
int i =99;
double t= const_cast<double > (i);//错误不能使用它来改变类型
它常常是用于有函数重载的上下文中。
reinterpret_cast:
它通常为运算对象的位模式提供男儿何不带较低层次上的重新解释。
int *pi ;
char *pc = reinterpret_cast<char *> (pi);//这是正确的
pc 所指的对象是一个int 而不是字, 如果把pc当成普通的字符指针使用就有可能在运行时发生错误。
int i = 99;
int *pi =&i;
char *pc = reinterpret_cast<char *> (pi);//这是正确的
char iu= *pc;
cout<<iu<<endl;//输出c
cout<<*pc<<endl;//输出c
cout<<*pi<<endl;//输出99
使用它是非常危险的,我们尽量避免使用它。
类型转换会干扰了正常的类型检查,建议避免使用强制类型转换。
dynamic_cast:
RTTI:运行时类型识别的功能由两个运算符实现:
typeid 运算符,用于返回表达式的类型。(我们不知道一个表达式是什么类型的时候,可以使用它查看)
dynamic_cast 运算符,用于将基类的指针或引用安全地转换成派生类的指针或引入。
它的使用形式:
dynamic_cast <type*> (e*);
dynamic_cast <type*> (e&);
dynamic_cast <type*> (e&&);
代码中的 type 必须是一个类类型,通常情况下该类型应该含有虚函数,第一行代码中的 e 必须是一个有效的指针。第二行中的 e 必须是一个左值。 在第三行中 e 不能是左值。
上面所有形式的中的e 必须符合下面三个条件中的任意一个:
e 的类型是目标 type 的公有派生类, e 的类型是目标 type 的公有基类或者 e 的类型就是目标 type 的类型。
指针类型转换失败结果为 0 , 转换目标为引用类型并且转换失败了,它会抛出一个 bad_cast 异常(这个异常定义在 typeinfo 标准库头文件中)。
我们可以对一个空指针执行 dynamic_cast ,结果是所需类型的空指针。