zoukankan      html  css  js  c++  java
  • dynamic_cast 转换示例

    dynamic_cast 转换示例

    /*
    带虚函数与不带虚函数转换的区别
    
    dynamic_cast:必须要有虚函数才可以转换
    dynamic_cast:只能处理转换指针或引用,不能转换对象
    dynamic_case 只能识别多态数据类型,转换失败就是null
    多态,父类指针可以根据多态转化为子类指针
    子类指针存储一个父类指针,转换失败。指针为 00000
    子类指针转换成父类,自动转换
    
    typeid:自动识别类型,依赖于虚函数
    
    
    //虚函数重载和返回值无关 和参数的类型 个数 顺序有关
    //虚函数被继承下来了还是虚函数
    //如果要使用被继承的虚函数 不允许出现虚函数重载和覆盖
    //多态可以跨类 爷爷辈的指针 可以存储孙子辈的地址 父辈拔针的地址 
     */
    
    #include <iostream>
    
    /* 
    没有虚函数的情况下,子类同名函数会覆盖父类, 
    父类指针存储子类地址: 
                    1、有虚函数情况:调用子类方法 
                    2、没有虚函数情况:调用父类方法 
    */
    class base1
    {
    public:
        virtual void show()
        {
            std::cout << "base1->show()" << std::endl;
        }
    };
    
    class baseX: public base1
    {
    public:
        void show()
        {
            std::cout << "baseX->show()" << std::endl;
        }
    };
    
    class base2
    {
    public:
        void show()  // 注意: 不是虚函数
        {
            std::cout << "base2->show()" << std::endl;
        }
    };
    
    class baseY: public base2
    {
    public:
        void show()
        {
            std::cout << "baseY->show()" << std::endl;
        }
    };
    
    
    int main()
    {
        //多态,父类指针可以根据多态转化为子类指针  
        //子类指针存储一个父类指针,转换失败。指针为 0x00000000 
        base1 *p1 = new base1;
        base1 *p2 = new baseX;
        std::cout << "p1 addr: 0x" << p1 << " " << "p2 addr: 0x" << p2 << std::endl;
        p1->show();
        p2->show();
    
        //typeid:自动识别类型,依赖于虚函数
        std::cout << typeid(p2).name() << std::endl; // p1的类型为父类类型指针 class base1 *
        std::cout << typeid(*p2).name() << std::endl; // *p1的类型为子类类型 class baseX
    
        baseX *px = dynamic_cast<baseX *>(p1); // 使用子类指针存储一个父类指针
        std::cout << "px addr: 0x" << (void *)px << std::endl; // 转换失败,px的地址值为0x00000000
        // px->show(); // 可以通过编译,但是运行会崩溃
    
        base1 *pb1 = dynamic_cast<base1 *>(p2); // 使用父类指针存储一个子类指针
        std::cout << "pb1 addr: 0x" << (void *)pb1 << std::endl; // 转换成功
        pb1->show();
    
        std::cout << "===========================================" << std::endl;
    
        base2 *p3 = new base2;
        base2 *p4 = new baseY;
        std::cout << "p3 addr: 0x" << p3 << " " << "p4 addr: 0x" << p4 << std::endl;
        p3->show();
        p4->show();
    
        //typeid:自动识别类型,依赖于虚函数
        std::cout << typeid(p4).name() << std::endl; // p1的类型为父类类型指针 class base2 *
        std::cout << typeid(*p4).name() << std::endl; // *p1的类型为子类类型 class base2
    
        // 注意: 这里转换失败,是因为RTTI实时类型检测到p3和py的类型是不一样的,需要进行转换
        // 但是dynamic_cast转换只能识别多态数据类型,转换失败就是null
        // dynamic_cast:必须要有虚函数才可以转换
        //baseY *py = dynamic_cast<baseY *>(p3); // 使用子类指针存储一个父类指针
        //std::cout << "py addr: 0x" << (void *)py << std::endl; // 转换失败,px的地址值为0x00000000
        //px->show(); // 可以通过编译,但是运行会崩溃
    
        // 注意: 这里转换成功,是因为RTTI实时类型检测到p4和pb2的类型是一样的,无需转换,直接赋值即可
        base2 *pb2 = dynamic_cast<base2 *>(p4); // 使用父类指针存储一个父类指针
        std::cout << "pb2 addr: 0x" << (void *)pb2 << std::endl; // 转换成功
        pb2->show();
    
        //std::cout << "mytest" << std::endl;
        system("pause");
        return 0;
    }

    运行结果

  • 相关阅读:
    题解「CF204E Little Elephant and Strings」
    题解「CF1000G Two-Paths」
    消息机制及按钮实效性
    View(视图)——消息机制
    城市线程练习题后续
    城市线程练习题
    View(视图)——对话框之日期对话框和时间对话框文集
    View(视图)——对话框之进度对话框
    删除对话框练习
    拨打电话与发送短信功能
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/7693149.html
Copyright © 2011-2022 走看看