形式:
cast-name<type>(expression)
type 是转换的目标类型,expression 是要转换的值。
1.static_cast
任何具有明确定义的类型转换,只要不包含底层const,都可以使用 static_cast。
例如
double a = 3.14;
int b = 3;
int a1 = static_cast<int>(a); //double转int
double b1 = static_cast<double>(b); //int转double
2.const_cast
只能改变运算对象的底层const(底层const含义请自行查阅资料)
const_cast中的类型必须是指针、引用或指向对象类型成员的指针。引用的const都是底层const。
例如
/*1.指针*/
const char a = 'a';
//pc是指向常量的指针,即自己可变,所指内容不可变
const char *pc = &a;
//现在可以通过修改 *p 来修改所指内容了,但是仍不能通过 a 和 *pc 进行操作
char *p = const_cast<char*>(pc);
/*2.引用*/
int temp = 2;
//不能改变q的值,引用的const都是底层const
const int& q = temp;
int& h = const_cast<int &>(q);
//可以改变h的值,此时temp的值是12
h = 12;
3.reinterpret_cast
这种类型转换实际上是强制编译器接受 static_cast 通常不允许的类型转换,它并没有改变指针的二进制表示,只是改变了编译器对原对象的的解释方式。
例如
int cc = 12;
int *p = &cc;
char *pc = static_cast<char*>(p); //编译器会报错,不允许这样转换
char *pc = reinterpret_cast<char*>(p); //编译器不报错
使用 reinterpret_cast 是非常危险的,尽量不要使用它。
4.dynamic_cast
此运算符用于将基类的指针或引用安全地转换成派生类的指针或引用。
适用情况:我们想使用基类对象的指针或引用执行某个派生类操作并且该操作不是虚函数。(只要有可能我们应尽量使用虚函数)
例如:
基类:A
派生类(公有继承A类):B
派生类(公有继承B类):C
A *P = new B;
//此时我们想调用B的一个函数,但是该函数不是虚函数,没办法用P调用,这时让一个派生类指针指向这个对象
B *P1 = P; //错误,A*类型的值不能用于初始化 B*类型的实体
B *P1 = dynamic_cast<B*>(P); //正确
C *P2 = dynamic_cast<C*>(P); //编译没有问题,但运行时会产生错误,因为P动态类型是B类型
5.旧式的强制类型转换
type(expr); //函数形式的强制类型转换
(type)expr; //C语言风格的强制类型转换
旧式的强制类型转换分别具有与 static_cast,const_cast 或 reinterpret_cast 相似的行为。当我们使用它时,若转换成 static_cast 和 const_cast 也合法,则其行为与对应的命名转换一致;若不合法,则它执行与 reinterpret_cast 类似的功能。
char *pc = (char*)ip; //ip是指向整数的指针