zoukankan      html  css  js  c++  java
  • 关于dynamic_cast

    http://www.groad.net/bbs/read.php?tid-5476.html

    dynamic_cast 进行运行时强制转换。如果在执行时转换非法,则会转换失败。dynamic_cast 的通用形式如下:

    dynamic_cast <target-type> (expr)


    其中 target-type 指定了强制转换的目标类型expr 是需要进行强制转换的表达式。

    目标类型必须是指针类型或引用类型,也就是说,表达式也必须能够被求值为指针类型或者引用类型的结果。

    dynamic_cast 主要被用来执行多态类型之间的强制转换。比如两个多态类 B 和 D,且 D 派生于 B,此时我们可以用 dynamic_cast 将 D* 指针类型转换为 B* 类型,这是因为基类型的指针通常可以指向派生类的对象。然而,只有当指针指向的对象确实是类 D 的对象时,dynamic_cast 才能将指针从类型 D* 转换为类型 B* 。

    如果转换指针的类型失败时,经过 dynamic_cast 运算后得到的指针为空值。
    如果转换引用的类型失败时,则会抛出 bad_cast 类型异常。

    下面示例中,假设 Base 是多态类,Derived 派生于 Base ,那么:

    1
    2
    3
    4
    5
    6
    Base *bp, b_ob;
    Derived *dp, d_ob;
     
    bp = &d_ob;           // 基类型的指针可以指向派生类的对象
     
    dp = dynamic_cast<Derived *> (bp);   //强制转换基类指针为派生类指针,做法正确


    上面,将基类指针 bp 强制转换为派生类指针 dp 是可以的,这是因为 bp 指向的对象确实是一个 Derived 类型的对象。

    下面的是强制转换失败的示例:

    1
    2
    bp = &b_ob;
    dp = dynamic_cast<Derived *>(bp);    //错误


    现在 bp 是一个指向基类对象的指针,这时不能 dynamic_cast 将其强制转换为派生类对象的指针,因为派生类对象的指针不能指向基类的对象。

    下面是代码测试多种 dynamic_cast 的情况:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    // dynamicast.cpp : 定义控制台应用程序的入口点。
    //
     
    #include "stdafx.h"
    #include <iostream>
    using namespace std;
     
    class Base {
    public:
        virtual void f() { cout << "Inside Base. "; }
    };
     
    class Derived : public Base {
    public:
        void f() { cout << "Inside Derived "; }
    };
     
    int _tmain(int argc, _TCHAR* argv[])
    {
        Base *bp, b_ob;
        Derived *dp, d_ob;
     
        dp = dynamic_cast<Derived *>(&d_ob);    //派生类对象的指针强制转换为派生类对象的指针 OK
        if (dp) {
            cout << "Cast from Derived * to Derived * OK. ";
            dp->f();
        } else
            cout << "Error ";
        cout << endl;
     
        bp = dynamic_cast<Base *>(&d_ob);  //派生类对象的指针强制转换为基类的指针 OK(基类指针可以指向派生类的对象)
        if (bp) {
            cout << "Cast from Derived * to Base * OK. ";    
            bp->f();
        } else
            cout << "Error ";
        cout << endl;
     
        bp = dynamic_cast<Base *>(&b_ob);   //基类的指针强制转换为基类的指针 OK
        if (bp) {
            cout << "Cast from Base * to Base * OK. ";
            bp->f();
        } else
            cout << "Error ";
        cout << endl;
     
        dp = dynamic_cast<Derived *>(&b_ob);    //基类对象的指针(地址)强制转换为派生类的指针(失败)
        if(dp)
            cout << "Error ";
        else
            cout << "Cast from Base * to Derived * not OK. ";
         
        cout << endl;
     
        bp = &d_ob;        //bp 指向派生类的对象
         
        dp = dynamic_cast<Derived *> (bp);       //可以,因为 bp 确实已经指向了派生类
        if(dp) {
            cout << "Casting bp to Derived * OK " << "because bp is really pointing "
                 << "to a Derived object. ";
                 dp->f();
        }else
            cout << "Error ";
        cout << endl;
     
        bp = &b_ob;        //bp 指向基类型对象
        dp = dynamic_cast<Derived *> (bp);  //失败,因为 bp 现在已经确实指向了基类对象
        if(dp)
            cout << "Error";
        else {
            cout << "Now casting bp to a Derived * "
                  << "is not OK because bp is really "
                  << "pointing to a Base object. ";
        }
        cout << endl;
     
        dp = &d_ob;        //dp 指向派生类对象
        bp = dynamic_cast<Base *> (dp);    //可以,基类指针可以指向派生类对象
        if (bp) {
            cout << "Casting dp to a Base * is OK. ";
            bp->f();
        }else
            cout << "Error ";
     
        return 0;
    }


    运行输出:

    Cast from Derived * to Derived * OK.
    Inside Derived

    Cast from Derived * to Base * OK.
    Inside Derived

    Cast from Base * to Base * OK.
    Inside Base.

    Cast from Base * to Derived * not OK.

    Casting bp to Derived * OK
    because bp is really pointing
    to a Derived object.
    Inside Derived

    Now casting bp to a Derived *
    is not OK because bp is really
    pointing to a Base object.

    Casting dp to a Base * is OK.
    Inside Derived
  • 相关阅读:
    Java io 理解
    Java应用的理解
    Flyweight 享元模式
    Bridge 桥梁模式
    Decrator 装饰模式
    [CF997C]Sky Full of Stars_二项式反演_等比数列_容斥原理
    [CF1010D]Mars Over_位运算性质
    [CF991D]Bishwock_状压dp
    [Agc030B]Tree Burning_贪心
    [Cometoj#4 E]公共子序列_贪心_树状数组_动态规划
  • 原文地址:https://www.cnblogs.com/buxianghe/p/3257172.html
Copyright © 2011-2022 走看看