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

    C++中的四种强制类型转换除了具有C语言强制类型转换的功能外,还可提供更好的控制强制转换的过程;能更清晰地表明程序员的意图,程序员只有看到这样的代码,立即就能知道一个强制类型转换的目的。 

    C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是: TYPE b = (TYPE)a,而C++风格的类型转换提供了四种类型转换操作符来对应不同的场景,使用格式是: TYPE b = 强制转换类型符<TYPE>(a)。 

     Const_cast常用于去掉类型的const或volalitle属性,只能用于指针和引用的,无法对变量进行使用,以便对const变量进行赋值等操作。 Dynamic_cast能够安全地用于类之间的类型转换,如父类转换为子类,或者子类转换为父类。很多场合能使用static_cast的地方可以使用dynamic_cast来替换。 Static_cast更多地用于基本数据类型之间的转换.reinterpret_cast主要用于转换不相容的数据类型,如线程函数传递的this指针数据换为原来的数据类型。不建议使用

     

    一、 reinterpret_cast 

    reinterpret_cast主要用于转换不相容的数据类型,特别是能够把任何数据类型转换为指针类型和引用类型,以及相反的过程,也可以用于指针之间的转换。 错误使用reinterpret_cast操作符很容易产生不安全的行为,因此,尽量使用其他三种转换操作符。 

    二、 static_cast 

    类似于C风格的强制类型转换,是无条件的转换和静态的转换,用于:

     1. 基类和子类之间的转换:子类指针转换成父类是指针是安全的;但父类指针转换成子类指针是不安全的。 

    2. 基本数据类型转换,如enum,struct,int,char,float等。

     3. 空指针转换成目标类型的指针。 

    4. 任何类型的表达式转换成void类型。 

    5. Static_cast不能去掉类型的const,volitale属性。 

    int n = 6; 

    double d = static_cast<double>(n);//基本类型转换 int *pn = &n; 

    //double *d = static_cast<double>(&n);//无关类型指针转换,编译错误 void* p = static_cast<void*>(pn);//任意类型转换成void类型 

    6. 如果涉及到类的话,static_cast只能在有相互联系的类型中进行相互转换,不能进

    行无关类类型指针之间的转换(如非基类和子类)。 

          class A      {};  

         class B:public A   {};  

         class C      {};  

         A* a = new A;    

        B* b;     

     C* c;  

         b = static_cast<B*>(a);//父类转子类,编译不会报错,B类继承A类      //c = static_cast<B*>(a);//编译报错,C类与A类没有任何关系  

    三、 dynamic_cast 

    static_cast转换没有dynamic_cast转换安全。因为static_cast不进行运行时检查,而dynamic_cast会进行运行时检查。当对于一个模糊指针使用static_cast时不会报错,使用dynamic_cast时会报错。 

    虽然dynamic_cast是安全的,dynamic_cast仅仅对指针和引用有效,并且允许时检查也会影响效率。 

    用法:dynamic_cast< type-id > ( expression )。 

    该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void*;如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。 

    classB { public: intm_iNum;

    virtualvoidfoo(); };

    classD: publicB { public:

    char* m_szName[100]; };

    voidfunc(B* pb) {

    D* pd1 = static_cast<D*>(pb); D* pd2 = dynamic_cast<D*>(pb); }

    在上面的代码段中,如果pb指向一个D类型的对象,pd1和pd2是一样的,并且对这两个指针执行D类型的任何操作都是安全的;但是,如果pb指向的是一个B类型的对象,那么pd1将是一个指向该对象的指针,对它进行D类型的操作将是不安全的(如访问m_szName),而pd2将是一个空指针。 

    四、 const_cast 

    1、去掉类型的const或volalitle属性,如: 

    structSA {  inti; SA(void)         { i = 0;         }     };  constSAra; 

    /*    ra.i = 10;//直接修改const类型,编译错误“:error C3892: “ra”: 不能给常量赋值”*/  

    SA&rb = const_cast<SA&>(ra); rb.i = 10; 

    2、把一个本来不是const类型的数据转换成const类型。 

    voidreadonly(constchar* s); char* p1 = newchar[12];  

    readonly(p1);

    //隐式转换为const char*类型 //

    readonly(const_cast<const char*>(p1));//显式 

    3、const_cast操作不能在不同的种类间转换。

  • 相关阅读:
    设计模式-可复用面向对象软件基础笔记
    C#--笔记
    win系统下nodejs安装及环境配置
    三步将Node应用部署到Heroku上 --转载
    Ubuntu 重启命令
    Ubuntu ssh免密登录
    Ubuntu Hadoop环境搭建(Hadoop2.6.5+jdk1.8.0_121)
    Ubuntu vim使用
    Scala学习——array与arraybuffer的区别(初)
    Scala学习——可变参数(初)
  • 原文地址:https://www.cnblogs.com/davy2013/p/3147420.html
Copyright © 2011-2022 走看看