const_cast:从字面意思上就可以理解,去除变量的const属性。
static_cast:静态类型转换,一般用于基本类型间的转换,如char->int
dynamic_cast:动态转换,同于多态之间的类型转换
reinterpret_cast:用于不同类型的指针类型的转换。
const_cast
int main(int argc,char** argv)
{
const int a = 5;
//int &b = a; //直接修改const类型编译期会报错
int &b = const_cast<int&>(a);
b = 6;
cout << &a <<endl;
cout << &b <<endl;
cout << a <<endl;
cout << b <<endl;
}
输出为
0x7ffd68b915cc
0x7ffd68b915cc
5
6
我们可以看到a的内存位置的数据确实被修改了,但是同一个内存位置为什么a与b的输出值不同呢?一种解释是编译器进行了常量折叠的优化,因为a声明为了const常量,因此编译器认为它是一个在编译期就可以确定值的常量,因此程序中使用a变量时不会去对应的内存寻值,而是直接替换成其初始化值5。
static_cast
静态转换相当于c中的强制转换,无条件转换,静态类型转换。主要用途如下:
1. 基类与子类间的转换:子类指针转成基类指针是安全的,基类指针转成子类指针是不安全的,因此一般使用dynamic_cast
2. 基本类型间的转换,如int,char,double等。静态转换不能用于无关类型指针的转换,如int*->double* 是错误的
3. 把空指针转换成目标类型的空指针
4. 把任何类型的表达式转换成void类型
int n = 40;
double m = static_cast<double>(n); //成功,基本类型的转换
int *pn = &n;
double *d = static_cast<double*>(pn); //编译错误,不同类型的指针int*和double* 无法互相转换
void *v = static_cast<void*>(pn); //成功,转换成void型指针
int *i = static_cast<int*>(nullptr); //成功,将空指针转换成int型空指针
dynamic_cast
有条件转换,动态类型转换,运行时会进行类型安全检查(失败时返回空指针)。它是继承类间安全的指针转换方法。不允许进行静态类型转换,即参与转换的必须是指针或者引用。
- 子类指针转成基类指针是安全的
- 基类指针转成子类指针是不安全的,因为此时调用子类独有的数据时可能发生数据越界,因此返回nullptr
- 同基类下的不同子类间的指针转换也是不安全的,因此返回nullptr
reinterpret_cast
这种转换仅仅重新解释类型,没有进行二进制的转换
- 转换的类型必须是指针,引用,算数类型,函数指针或者成员指针
- 在比特位上的转换,可以把指针转成整数,再把整数重新转成指针
- 最普遍的用途在于函数指针间的转换
- 难以保证移植性
int a = 10;
int *pa = &a;
long int num = reinterpret_cast<long int>(pa); //将指针转换成long int整数类型