zoukankan      html  css  js  c++  java
  • 【C++】 四种强制类型转换(static_cast 与 dynamic_cast 的区别!)

    1. static_cast

    实现C++种内置基本数据类型之间的相互转换,不能用于两个不相关类型进行转换。

    例如:将整形数据转换为浮点型

    1. c语言方式
    int a = 8;
    int b = 3;
    double result = (double)a / (double)b;
    
    • 1
    • 2
    • 3
    1. C++方式
    int a = 8;
    int b = 3;
    double result = static_cast<double>(a) / static_cast<double>(b);
    
    • 1
    • 2
    • 3

    格式如下:

    static_cast<类型>(变量表达式)

    应用场景:

    • 用于类层次结构中基类和派生类之间引用或指针的转换。
      进行上行转换(把派生类的指针或引用转换成基类表示)是安全的。
      进行下行转换(把基类的指针或引用转换成派生类表示),由于没有动态类型检查,不安全。
    • 用于基本数据类型之间的转换
    • 把空指针转换成目标类型的空指针
    • 把任何类型的表达式转换成void类型

    2. dynamic_cast

    用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)。

    dynamic_cast< type_id >(expression)

    • type_id 必须是类的指针、类的引用或者void*。
    • 主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
    • dynamic_cast只能用于含有虚函数的类;
    • 进行上行转换的时候,与static_cast 的作用一样。下行转换的时候,具有类型检查的功能,比static_cast更安全。
    • dynamic_cast会先检查是否能转换成功,如果能则转换,不能则返回0。
    class B
    {
    public:
        int m_iNum;
        virtual void foo();
    };
     
    class D : public B
    {
    public:
        char *m_szName[100];
    };
     
    void func(B *pb)
    {
        D *pd1 = static_cast(pb);
        D *pd2 = dynamic_cast(pb);
    }
    
    • 1
    • 2

    如果pb指向一个D类型的对象,pd1 和 pd2 是一样的,并且这两个指针执行D类型的任何操作都是安全的。

    如果指向B的对象,那么pd1将是一个指向该对象的指针,对它进行D类型的操作是不安全的。pd2将是一个空指针。

    B要有虚函数:

    这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表中,只有定义了虚函数的类才有虚函数表,没有定义虚函数的类是没有虚函数表的。

    3. const_cast

    c语言中,const是用来限定变量,表示该变量的值不能更改。

    const_cast 是用来强制去掉这种不能被修改的常数特性。不是去除变量的常量性,而是去除指向常数对象的指针或引用的常量性,对象必须为指针或引用。

    const_cast<type_id>(expression)

    用来修改类型的const或volatile属性。

    常量指针被转化成非常量指针,并且仍然指向原来的对象;
    常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。

    include<iostream>
    using namespace std;
     
    int main()
    {
        const int a = 10;
        const int * p = &a;
        int *q;
        q = const_cast<int *>(p);
        *q = 20;    //fine
        cout <<a<<" "<<*p<<" "<<*q<<endl;
            cout <<&a<<" "<<p<<" "<<q<<endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    定义了一个普通指针q。将p通过const_cast去掉其常量性,并赋值给q指针。

    4. reinterpret_cast

    通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型。

    reinterpret_cast<type_id>(expression)

    type_id 必须是一个指针、引用、算术类型、函数指针、成员指针。

    应用场景:

    改变指针或引用的类型、将指针或引用转换为一个足够长度的整形、将整形转换为指针或引用。

    int *a = new int;
    double *d = reinterpret_cast<double *>(a);
    
    • 1
    • 2

    5. 为什么要需要四种类型转换?

    C风格的转换格式很简单,但是也有缺点:

    • 过于粗暴,可以在任意类型之间转换,很难判断其正确性。
    • 隐式转换有些情况会出问题:比如精度丢失。
    • 显示转换和隐式转换混合在一起,很难快速定位全部的强制转换语句。

    但是在实际的工程中强制转换是不可避免的,为此C++提供的四种强制类型转换提供了更加安全可靠的转换。

  • 相关阅读:
    剑指offer:2.二维数组的查找(Java版)
    剑指offer:1.找出数组中重复的数(java版)
    Java自动内存管理机制学习(二):垃圾回收器与内存分配策略
    Java自动内存管理机制学习(一):Java内存区域与内存溢出异常
    Java并发编程学习:线程安全与锁优化
    Java并发编程学习:volatile关键字解析
    Java 8之重新认识HashMap
    【转】java内部类的作用分析
    不能进入String.class调试
    SCJP考试题310-025(第二套<4>)92-147/147
  • 原文地址:https://www.cnblogs.com/bruce1992/p/14322678.html
Copyright © 2011-2022 走看看