c++ dynamic_cast

#pragma once

#include "XLogger.h"
#include <iostream>

/**
 * dynamic_cast<type_id>(expression);
 * 是一种用于在运行时进行类型安全转换的操作符,主要用于将基类指针或引用转换为派生类指针或引用。
 *  它是C++中唯一一种在运行时进行类型检查的类型转换。dynamic_cast主要用于以下情况:
 *      多态类型转换:将基类指针或引用转换为派生类指针或引用。
 *      类型安全:确保转换是安全的,即只有在转换是有效的情况下,转换才会成功。
 *
 * 使用dynamic_cast的原因
 *  在面向对象编程中,特别是在继承和多态的情况下,可能需要将基类对象转换为派生类对象。使用dynamic_cast可以确保转换的对象是有效的,
 *          并且可以在运行时检查类型,以防止无效的转换导致程序崩溃。
 *
 * 使用方法
 *  指针类型转换:将基类指针转换为派生类指针。如果转换失败,结果为nullptr。
 *  引用类型转换:将基类引用转换为派生类引用。如果转换失败,抛出std::bad_cast异常。
 *
 *
 * 语法
 * dynamic_cast<type*>(expression);//type*:目标类型的指针。expression:要转换的表达式,通常是基类的指针或引用。
 * dynamic_cast<type&>(expression);//type&:目标类型的引用。
 *
 * 注意事项(来源 https://blog.youkuaiyun.com/weixin_43798887/article/details/118424172)如下:
 *  是运行时处理的,运行时会进行类型检查(这点和static_cast差异较大)
 *  不能用于内置基本数据类型的强制转换,并且dynamic_cast只能对指针或引用进行强制转换
 *  如果转换成功的话返回的是指向类的指针或引用,转换失败的话则会返回nullptr
 *  进行上行转换时,与static_cast的效果是完全一样的
 *  使用dynamic_cast进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
 *      并且这种情况下dynamic_cast会要求进行转换的类必须具有多态性(即具有虚表,直白来说就是有虚函数或虚继承的类),否则编译不通过
 *      需要有虚表的原因:类中存在虚表,就说明它有想要让基类指针或引用指向派生类对象的情况,
 *      dynamic_cast认为此时转换才有意义(事实也确实如此)。而且dynamic_cast运行时的类型检查需要有运行时类型信息,这个信息是存储在类的虚表中的
 * 在C++中,编译期的类型转换有可能会在运行时出现错误,特别是涉及到类对象的指针或引用操作时,更容易产生错误。
 *      dynamic_cast则可以在运行期对可能产生问题的类型转换进行测试
 *
 */

class DynamicBase {
public:
    virtual ~DynamicBase() {}
};

class DynamicDerived : public DynamicBase {
public:
    void derivedFunction() {
        XLOG_INFO("DynamicDerived function called");
    }
};

class AnotherDynamicDerived : public DynamicBase {
};

class Dynamic_cast {
public:
    Dynamic_cast() {}

    void task1() {
        DynamicBase *pDerived = new DynamicDerived();
        DynamicBase *pAnotherDynamicDerived = new AnotherDynamicDerived();

        task2(pDerived);//DynamicDerived function called
        task2(pAnotherDynamicDerived);//Conversion failed

        delete pDerived;
        delete pAnotherDynamicDerived;
    }

    void task2(DynamicBase *base) {
        DynamicDerived *dynamicDerived = dynamic_cast<DynamicDerived *>(base);
        if (dynamicDerived) {
            dynamicDerived->derivedFunction();
        } else {
            XLOG_INFO("Conversion failed");
        }
    }

    void task3() {
        std::string name = "abcd";
        std::string *str_ptr = &name;
        //error : dynamic_cast的目标类型'DynamicDerived'无效;目标类型必须是指向已定义类的引用或指针类型
        //DynamicDerived *dynamicDerived = dynamic_cast<DynamicDerived>(str_ptr);
    }

    ~Dynamic_cast() {}

private:
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值