四种强制类型转换

为什么需要更加细粒度的强制类型转换?

C语言中的显示强制转换能够强调风险,要程序员意识到他在做什么
但是粒度过大,C风格的强制类型转换统一使用(),而()在代码中随处可见,所以也不利于使用文本检索工具(例如 Windows 下的 Ctrl+F、Linux 下的 grep 命令、Mac 下的 Command+F)定位关键代码。

在c++中有4中强制类型转换

关键字 说明
static_cast 用于良性转换,一般不会导致意外发生,风险低
const_cast 用于const与非const,volatile与非volatile之间的转换
reinterpret_cast 高度危险的转换,这种转换仅仅是对二进制位的重新解释,不会借助已有的转换规则对数据进行调整,但是可以实现最灵活的 C++ 类型转换。
dynamic_cast 借助 RTTI(Run Time Type Identification),用于类型安全的向下转型(Downcasting)。

用法皆为:
xxx_cast<newType>(data)
C语言风格类型转换:

double scores = 95.5;
int n = (int)scores;

C++风格类型转换:

double scores = 95.5;
int n = static_cast<int>(scores);

static_cast

const_cast

reinterpret_cast

与C语言中的显示强转类似
风险很高,reinterpret_cast只是对二进制位的重新解释,不会借助已有的转换规则对数据进行调整。
reinterpret_cast 可以认为是 static_cast 的一种补充,一些 static_cast 不能完成的转换,就可以用 reinterpret_cast 来完成,例如两个具体类型指针之间的转换、int 和指针之间的转换(有些编译器只允许 int 转指针,不允许反过来)。

编译器处理,执行的是逐字节的复制
能够转换:

  • 不同类型间的指针
  • 不同类型的引用
  • 指针与能够容纳指针的整数类型之间的转换
#include <iostream>
using namespace std;
class A {
public:
    A(int a = 0, int b = 0): m_a(a), m_b(b){}
private:
    int m_a;
    int m_b;
};
class Father {
};
class Son : public Father {
};
int main(){
    //将 char* 转换为 float*
    char str[]="http://c.biancheng.net";
    float *p1 = reinterpret_cast<float*>(str);
    cout<<*p1<<endl;
    //将 int 转换为 int*
    int *p = reinterpret_cast<int*>(100);
    //将 A* 转换为 int*
    p = reinterpret_cast<int*>(new A(25, 96));
    cout<<*p<<endl;
    // 甚至可以把子类指针转向父类
    Son* son;
    Father* father = nullptr;
    son = reinterpret_cast<Son*>father;

    return 0;
}

dynamic_cast

posted @ 2022-02-27 21:10  抿了抿嘴丶  阅读(168)  评论(0编辑  收藏  举报