c++的四种强制类型转换

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

有条件转换,动态类型转换,运行时会进行类型安全检查(失败时返回空指针)。它是继承类间安全的指针转换方法。不允许进行静态类型转换,即参与转换的必须是指针或者引用。

  1. 子类指针转成基类指针是安全的
  2. 基类指针转成子类指针是不安全的,因为此时调用子类独有的数据时可能发生数据越界,因此返回nullptr
  3. 同基类下的不同子类间的指针转换也是不安全的,因此返回nullptr

reinterpret_cast

这种转换仅仅重新解释类型,没有进行二进制的转换

  1. 转换的类型必须是指针,引用,算数类型,函数指针或者成员指针
  2. 在比特位上的转换,可以把指针转成整数,再把整数重新转成指针
  3. 最普遍的用途在于函数指针间的转换
  4. 难以保证移植性
int a = 10;
int *pa = &a;
long int num = reinterpret_cast<long int>(pa);  //将指针转换成long int整数类型

猜你喜欢

转载自blog.csdn.net/acelove40/article/details/79862738