• C++风格的转型运算符小结


    C++风格的转型运算符小结

    为了改正C中丑陋的转型操作,C++中引入了四个新的转型操作符,分别是:
    dynamic_cast
    const_cast
    static_cast
    reinterpret_cast

    1.dynamic_cast
    这个转型操作符主要用在安全的向下转型(safe downcasting)中,也就是从基类指针/引用向派生类指针/引用的转型。例如:
    Code: [View More of this Code] [View Even More of this Code] [View Less of this Code] [Select All of this Code]

    class A {...};
    class B:public A {...};
    A* a = new B;
    B* b;
    b = dynamic_cast<B *> a;

    当你将dynamic_cast用在指针上时,如果成功,就传回一个转型目标的指针,如果失败,则传回null指针。所以用到dynamic_cast的 时候必然会导致if-then-else的程序风格,其中else就是用来检测转型失败的情况([1]第39条)。例子如下:
    Code: [View More of this Code] [View Even More of this Code] [View Less of this Code] [Select All of this Code]
    #include <iostream>
    using namespace std;

    class A {
    public:
     virtual void do_sth(){
      cout<<"aaa\n";
     }

    };
    class B : public A {
    public:
     virtual void do_sth(){
      cout<<"bbb\n";
     }

    };
    class C : public A {
    public:
     virtual void do_sth(){
      cout<<"ccc\n";
     }
     
    };

    int main(){
     A* a1 = new B;
     A* a2 = new C;
     B* b;

     if(b = dynamic_cast<B *>(a1))//转换成功
      b->do_sth();
     else
      cout<<"error\n";
     
     if(b = dynamic_cast<B *>(a2))//转换失败
      b->do_sth();
     else
      cout<<"error\n";
    }


    2.const_cast
    此转型操作符用来将对象或指针的常量性(sonstness)转型掉。例如:

    const A * a1;
    A * a2 = const_cast<A *> (a1);

    需要注意的是,const_cast转型并不总是成功的,当遇到转型的对象本身就是const的时候,那么将其常量性转型,结果未定义。看一下下面的例子:
    Code: [View More of this Code] [View Even More of this Code] [View Less of this Code] [Select All of this Code]

    // constcast.cpp from [2]
    #include <iostream>
    using std::cout;

    void change(const int * pt, int n);

    int main()
    {
        int pop1 = 38383;
        const int pop2 = 2000;

        cout << "pop1, pop2: " << pop1 << ", " << pop2 << '\n';
        change(&pop1, -1);
        change(&pop2, -1);
        cout << "pop1, pop2: " << pop1 << ", " << pop2 << '\n';

        return 0;
    }

    void change(const int * pt, int n)
    {
        int * pc;
        if (n < 0)
        {
            pc = const_cast<int *>(pt);
            *pc = 100;
        }
    }

    输出的结果是:
    pop1, pop2: 38383, 2000
    pop1, pop2: 100, 2000
    可见,pop2的值并没有改变(有些编译器会产生一个pop2的临时变量,并将其地址值赋给pc。在C++标准中,这种情况下的行为是不确定的[2])。

    3.static_cast
    此转型操作符用于内建数据类型之间的转型。它与C的转型操作最接近。当没有其他适当的转型操作符可用时,就使用它。它可以将整型转换为枚举型,双精度型转换为整型,浮点型转换为长整型等等。例如:
    Code: [View More of this Code] [View Even More of this Code] [View Less of this Code] [Select All of this Code]

        int n=9;
        double d = static_cast < double > (n);

    上面的例子中,我们将一个变量从 int 转换到 double. 这些类型的二进制表达式是不同的。要将整数 9 转换到 双精度整数 9,static_cast需要正确地为双精度整数 d 补足比特位。其结果为 9.0 。

    4.reinterpret_cast
    此转型操作符的结果取决于编译器,用于修改操作数类型,非类型安全的转换符。举例如下:
    Code: [View More of this Code] [View Even More of this Code] [View Less of this Code] [Select All of this Code]

    int main() { // from [2]
        struct dat { short a; short b;};
        long value = 0xA224B118;
        dat * pd = reinterpret_cast<dat *> (&value);
        cout << pd->a;   // display first 2 bytes of value
        return 0;
    }

    该例中将long型转换成struct,但此代码是不可移植的,在IBM兼容机和Mac机上的运行结果完全不一样,因为他们存储字节的方式不一样。
    reinterpret_cast的使用要非常的谨慎,例如将3中的例子改写如下:
    Code: [View More of this Code] [View Even More of this Code] [View Less of this Code] [Select All of this Code]

        int n=9;
        double d = reinterpret_cast<double & > (n);
      

    这次,与3的结果有所不同。在进行计算以后,d 包含无用值。这是因为 reinterpret_cast 仅仅是复制 n 的比特位到 d,没有进行必要的分析。

    以上是我在学习这些转型操作符一个小结,如有不对之处,请各位不啬赐教。
    大家有兴趣,可以去这里做一下有关这些转型操作符的练习。

    注:以上例子在 VC6 + Intel C++ Compiler 8.0 下编译运行通过(别忘了打开RTTI,加参数/GR)。

    参考文献:
    [1] Effective C++ 中文版 Scott Meyers 侯捷译
    [2] C++ Primer Plus, 4th Edition, Stephen Prata
    [3] STATIC_CAST VERSUS REINTERPRET_CAST(Topica转载)

    2005年1月22日 9:23

  • 相关阅读:
    性能测试入门
    PHP基础
    SpringCloud五大核心组件
    selenium(八)持续集成
    四种隔离级别和脏读、幻读、不可重复读
    RocketMQ【目录】
    ModelAgnostic Counterfactual Reasoning for Eliminating Popularity Bias in Recommender System
    How Powerful is Graph Convolution for Recommendation?
    ScoreBased Generative Modeling through Stochastic Differential Equations
    Graph Embedding for Recommendation against Attribute Inference Attacks
  • 原文地址:https://www.cnblogs.com/huqingyu/p/195728.html
Copyright © 2020-2023  润新知