zoukankan      html  css  js  c++  java
  • C++中四大强制类型转换!

    C++中有四中强制类型转换:static_cast,const_cast,reinterpret_cast,dynamic_cast,下面来逐一解释。


    1)static_cast<T* >(a)

    将地址a转换成类型T,T和a必须是指针、引用、基本数据类型或枚举类型。在运行时转换过程中,不进行类型检查来确保转换的安全性。

    class B { ... };
    
    class D : public B { ... };
    
    void f(B* pb, D* pd)
    
    {
    
       D* pd2 = static_cast<D*>(pb);        // 不安全, pb可能只是B的指针
       B* pb2 = static_cast<B*>(pd);        // 安全的
       ...
    
    }

    在C++语言中static_cast用于数据类型的强制转换,强制将一种数据类型转换为另一种数据类型。例如将整型数据转换为浮点型数据,它主要有如下几种用法:
        (1)用于类层次结构中基类和派生类之间指针或引用的转换,进行上行转换(把派生类的指针或引用转换成基类表示)是安全的,进行下行转换(把基类的指针或引用转换为派生类表示),由于没有动态类型检查,所以是不安全的。
        (2)用于基本数据类型之间的转换,如把int转换成char。这种转换的安全也要开发人员来保证
        (3)把空指针转换成目标类型的空指针
        (4)把任何类型的表达式转换为void类型
        注意:static_cast不能转换掉expression的const、volitale或者__unaligned属性。


    2)dynamic_cast<T* >(a)

    完成类层次结构中的提升,T必须是一个指针、引用或无类型的指针。a必须是决定一个指针或引用的表达式。表达式dynamic_cast<T*>(a) 将a值转换为类型为T的对象指针。如果类型T不是a的某个基类型,该操作将返回一个空指针。

    class A { ... };
    
    class B { ... };
    
    void f()
    {
    
      A* pa = new A;
    
      B* pb = new B;
    
      void* pv = dynamic_cast<A*>(pa);
    
      // pv 现在指向了一个类型为A的对象
    
      ...
    
      pv = dynamic_cast<B*>(pb);
    
      // pv 现在指向了一个类型为B的对象
    }

    用法:dynamic_cast<type_id> (expression)

       (1)其他三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查。

       (2)不能用于内置的基本数据类型的强制转换。

       (3)dynamic_cast转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。

       (4)使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。

            需要检测有虚函数的原因:类中存在虚函数,就说明它有想要让基类指针或引用指向派生类对象的情况,此时转换才有意只有定义了虚函数的类才有虚函数表。


    3)const_cast<T* >(a)

    去掉类型中的常量,除了const或不稳定的变址数,T和a必须是同类型。表达式const_cast<T*>(a)被用于从一个类中去除以下属性:const、volatile和_unaligned。

    class A { ... };
    
    void f()
    {
    
    const A *pa = new A;//const对象
    
    A *pb;//非const对象
    //pb = pa; // 这里将出错,不能将const对象指针赋值给非const对象
    pb = const_cast<A*>(pa); // 现在OK了
    ...
    }

    const_cast是用于强制去掉这种不能被修改的常数特性,但需要特别注意的是const_cast不是用于去除变量的常量性,而是去除指向常数对象的指针或引用的常量性,其去除常量性的对象必须为指针或引用。

    用法:const_cast<type_id> (expression)
       (1) 该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。
       (2)常量指针被转化成非常量指针,并且仍然指向原来的对象;
       (3)常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。


    4) reinterpret_cast<T* >(a)

    任何指针都可以转换成其它类型的指针,T必须是一个指针、引用、算术类型、指向函数的指针或指向一个类成员的指针。表达式reinterpret_cast<T*>(a)能够用于将char*到int*,或者One_class*到Unrelated_class*等类似这样的转换,因此是不安全的。

    class A { ... };
    
    class B { ... };
    
    void f()
    {
      A* pa = new A;
    
      void* pv = reinterpret_cast<A*>(pa);
      // pv 现在指向了一个类型为A的对象,这可能是不安全的
      ...
    }

    在C++语言中,reinterpret_cast主要有三种强制转换用途:改变指针或引用的类型、将指针或引用转换为一个足够长度的整形、将整型转换为指针或引用类型

    用法:reinterpret_cast<type_id> (expression)
       (1)    type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。
       (2) 它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。
        注意:在使用reinterpret_cast强制转换过程仅仅只是比特位的拷贝,因此在使用过程中需要特别谨慎!

     


    参考:http://www.cnblogs.com/tgycoder/p/5303701.html

    天上我才必有用,千金散尽还复来!
  • 相关阅读:
    敏捷开发之道(二)极限编程XP
    敏捷开发之道(一)敏捷开发宣言
    [原]项目进阶 之 持续构建环境搭建(四)Jenkins环境搭建
    [原]项目进阶 之 持续构建环境搭建(三)Maven环境搭建
    [原]项目进阶 之 持续构建环境搭建(二)Nexus私服器
    项目进阶 之 持续构建环境搭建(一)架构
    SVN备份教程(三)
    jQuery 层次选择器
    利用web workers实现多线程处理
    本地存储(localStorage、sessionStorage、web Database)
  • 原文地址:https://www.cnblogs.com/lutaishi/p/13436315.html
Copyright © 2011-2022 走看看