#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:
};