• 最好使用C++转型操作符


    旧式的C转型方式,几乎允许你将任何类型转换为任何其它类型,有其自身的缺陷,表现在以下两方面:

    不能更精确地指明其转型的意图。

       如将一个pointer-to-base-class-object 转型为一个pointer-to-derived-class-object(改变一个对象的类型)和将一个pointer-to-const-object转型为一个pointer-to-non-const-object(改变对象的常量性),在旧式C语法中并不区分。

    难以辨识。

      旧式C转型方式的语法为(type)expression,由一对小括号加上一个对象名称组成,而这种语法结构在C++的任何地方都有可能使用,这就无法很直观地判断出是否是转型操作

    为解决上述的缺点,C++引入4个新型转型操作符,分别为

        static_cast, const_cast, dynamic_cast, reinterpret_cast

    语法为:       ***_cast<type> (expression).

    下面着重解释四个新型操作符的用途:

    static_cast: 基本与拥有与C旧式转型相同的威力与意义,以及相同的限制。例如将一个非 const 的对象转换为 const 对象,或将int 转换为 double等等。它也可以用来执行上述多种转换的反向转换,例如将void*指针转为typed指针,将pointer-to-base转为pointer-to-derived。但是他无法将const转为non-const,这个只有const-cast才能够办到。如:

    /计算两个int型数相除,结果为double型
    int firstNum, secondNum;
    double res = (double)firstNum / secondNum;                //旧式C语法
    double res = static_cast<double>(firstNum) / secondNum;   //新式C++转型符

    const_cast: 用来改变表达式中的常量性(constness)或易变性(volatileness)。(换句话说:通常用来将对象的常量性转除(cast away the constness)。它是唯一有此能力的C++-style转型操作符如:

    int num;
    const int *cpNum = &num;
    int *pNum = cpNum;            //error:cannot convert from 'const int *' to 'int *'
    int *pNum = (int *)cpNum;                 //旧式C
    int *pNum = const_cast<int *>(cpNum);     //新式C++ const_cast移除常量性

    dynamic_cast: 用来执行继承体系中“安全的向下转型或跨系转型动作”也就是说你可以利用它将指向基类对象的指针或者引用转型为指向派生类对象的指针或引用,并得知转型是否成功。如果转型失败,会以一个null指针(当转型对象是指针)或个exception(当转型对象是引用)表现出来。dynamic_cast是唯一无法由旧式语法执行的转型动作,也是唯一可能消耗重大运行成本的转型作。如:

    //可以利用dynamic_cast将“指向base class object 的pointer或reference”转型为“指向derived class object的pointer或reference”
    //如果转型失败,会以一个null指针或一个exception 表现出来
    class CBase {     };                        //基类
    class CDerived: public CBase  {     };      //继承类
    CDerived dc;
    CDerived *dp = &dc;
    CBase *bp = dynamic_cast<CBase *>(dp);      //使用dynamic_cast将指向继承类的指针转化为指向基类的指针 
    CBase &br = dynamic_cast<CBase &>(dc);      //使用dynamic_cast将指向继承类的引用转化为指向基类的引用

    reinterpret_cast:意图执行低级转型,实际动作及结果可能取决于编译器,这也就表示它不可移植。例如将一个pointer to int 转型为int这一类转型在低级代码以外很少见。 最常用的用途是转换"函数指针"类型。如

    typedef void (*funcPtr)();    //funcPtr是个无参数返回值为void型的函数指针类型
    int iFunc(){return 0;}        //iFunc为一个无参数返回值为int型的函数
    void func(funcPtr f){}        //func函数的参数是一个类型为funcPtr类型的函数指针
    main()
    {
        func(iFunc());        //error:cannot convert parameter 1 from 'int' to 'void (__cdecl *)(void)'
        func(reinterpre_cast<funcPtr>(iFunc);     //right! reinterpre_cast将返回值为int 的函数转化为 返回值为void 的函数
    }

    参考:

    http://blog.csdn.net/hazir/article/details/7461118

      参考资料:

    《effective c++》 3th p117

    《more effective c++》 p12~16

     

     

     

     



  • 相关阅读:
    cmake Found package configuration file but it set OpenCV_FOUND to FALSE
    pthread库"timespec"结构体重定义解决
    【Windows10】运行软件后,窗口不显示的解决办法
    Windows下Cmake生成动态库install命令失败、导入库概念
    【转载】多尺度增强算法Retinex算法(MSRCR)的原理、实现及应用
    【转载】Ubuntu 和 Windows 之间进行远程访问和文件互传
    博客园Markdown编辑器
    合并两个有序数组(C++)
    从协方差矩阵的估算领会MATLAB矩阵编程思维
    常见排序算法的性能对比
  • 原文地址:https://www.cnblogs.com/youxin/p/2592376.html
Copyright © 2020-2023  润新知