• C++ 中 dynamic_cast 浅析


    简述:
    dynamic_cast 操作符,将基类的指针或引用安全的转换为派生类的指针或引用。主要讲解,dynamic_cast操作符的原理、使用方式、编译器设置、返回值等相关知识。
    dynamic_cast 操作符,将基类的指针或引用安全的转换为派生类的指针或引用。
    1. 原理
      将一个基类对象指针(或引用)cast (抛)到继承类指针,dynamic_cast 会根据基类指针是否真正指向继承类指针来做相应处理。

    2. 返回值
      对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针;
      对引用进行dynamic_cast,失败抛出一个异常,成功返回正常cast后的对象引用。 
    3. 注意
      dynamic_cast在将父类cast到子类时,父类必须要有虚函数。
    4. 对编译器的要求
      dynamic_cast<> 会用到RTTI技术,因此需要启动“运行时类型信息”这一选项,而在VC.net 2003中默认是关闭的。所以,需要人为的启动这一选项。否则编译器会警告:   
    warning C4541: “dynamic_cast”用在了带 /GR- 的多态类型“CBasic”上;可能导致不可预知的行为从而导致程序在运行时发生异常。 
    5. 编译器设置方法
      在 Project->Setting中 C/C++ -> C++ Language中设置。  
    首先,dynamic_cast依赖于RTTI信息,其次,在转换时,dynamic_cast会检查转换的source对象是否真的可以转换成target类型,这种检查不是语法上的,而是真实情况的检查。
    先看RTTI相关部分,通常,许多编译器都是通过vtable找到对象的RTTI信息的,这也就意味着,如果基类没有虚方法,也就无法判断一个基类指针变量所指对象的真实类型, 这时候,dynamic_cast只能用来做安全的转换,例如从派生类指针转换成基类指针。而这种转换其实并不需要dynamic_cast参与。
    也就是说,dynamic_cast是根据RTTI记载的信息来判断类型转换是否合法的。
    下面看一个例子:
    struct B1{
        virtual ~B1(){}
    };
    struct B2{
        virtual ~B2(){}
    };
    struct D1 : B1, B2{};
    int main()
    {
        D1 d;
        B1* pb1 = &d;
        B2* pb2 = dynamic_cast<B2*>(pb1);//L1
        B2* pb22 = static_cast<B2*>(pb1);  //L2
        return 0;
    }
    上述定义中可以看到,B1和B2是不相关的类,从L1可以看到,dynamic_cast允许这种转换:只要B1存在多态方法。
    L2将编译失败,static_cast并不允许两个完全不相干的类互相转换。

    
    
    进一步分析可参见:http://www.cnblogs.com/weidagang2046/archive/2010/04/10/1709226.html
  • 相关阅读:
    25-k个一组翻转链表 203-移除链表元素 206-反转一个链表
    24. 两两交换链表中的节点
    23-合并K个升序链表
    19-删除链表的倒数第N个节点
    18-四数之和
    21-合并两个有序链表
    双指针
    16-最接近的三数之和
    15-三数之和
    RobotFramework 断言关键字
  • 原文地址:https://www.cnblogs.com/space-place/p/7638578.html
Copyright © 2020-2023  润新知