C++中类型转换有哪几种?简述一下它们之间的区别。
参考回答 在C++ 中有4种类型转换方式,分别是static_cast、dynamic_cast、const_cast和reinterpret_cast。它们的主要区别如下: 1. static_cast功能:用于在相关类型之间进行转换,这些相关类型包括基本数据类型(如int和float)之间的转换,以及具有继承关系的类之间的向上转换(从派生类指针或引用转换为基类指针或引用)。它在编译时执行类型检查。 示例:1)基本数据类型转换:

输出演示结果:

2)类的向上转换:假设存在基类Base和派生类Derived

输出演示结果:

限制:虽然static_cast可以进行一些类型转换,但它不能用于无关类型之间的转换,比如将一个指针转换为一个完全不相关类型的指针(这种转换在逻辑上通常是不合理的)。

演示编译结果:

2. dynamic_cast功能:主要用于在具有继承关系的类之间进行安全的向下转换(从基类指针或引用转换为派生类指针或引用)。它在运行时进行类型检查,通过检查对象的实际类型来确定转换是否安全。如果转换是不安全的(即基类指针实际上并不指向派生类对象),则返回nullptr(对于指针类型)或抛出std::bad_cast异常(对于引用类型)。示例:假设存在基类Base和派生类Derived,


输出演示结果:

注意:dynamic_cast要求基类至少有一个虚函数。这是因为它依赖于运行时类型信息(RTTI),而只有在类中有虚函数时,编译器才会为该类添加RTTI信息。 3. const_cast功能:用于去除或添加变量的const限定符。它主要用于在某些特定情况下,比如在函数内部需要修改一个原本被声明为const的对象,但这种修改不会影响对象的外部常量性(例如通过一个非const的成员函数修改对象的内部状态,前提是这种修改不会改变对象在外部的常量语义)。示例:

在上面的main函数中,testFunc函数需要传递一个非const的int类型数据过去,这意味着可能会在函数内部修改数据;而在main函数中,我们只有一个常量a,想将其传递过去时,编译是会报错的,如下所示:

为了完成该参数的传递,此时我们可以使用const_cast去除常量a的const属性,修改成以下写法,就能编译通过了。

演示输出结果:

限制:const_cast只是改变了变量的常量性限定,不能用于改变变量的类型本身。并且如果通过const_cast去除const限定后对对象进行了不符合常量语义的修改(例如修改了一个原本不应该被修改的成员变量的值),可能会导致程序出现未定义行为。 4. reinterpret_cast功能:它是一种最“危险”的类型转换方式,用于在完全不同的类型之间进行转换,比如将一个指针转换为一个整数,或者将一个整数转换为一个指针,或者在不相关的指针类型之间进行转换。这种转换几乎不进行任何类型检查,只是简单地对二进制数据进行重新解释。示例:1)将整数转换为指针:

输出运行结果:

因为将地址为1的值交给了double型的执行b,解引用的结果是获取在地址为1的位置上的double类型数据,这就有问题了,程序直接报了段错误。由此可见,reinterpret_cast有点儿太无敌了,这很显然不是一个正常的使用方式。2)将整型地址传递给double型指针

输出演示结果:

虽然最终可以输出结果,但每次执行的结果都不一样,就是不确定的。所以对于reinterept_cast的使用,必须要非常清楚目的是什么,否则在使用时就会出现各种无法预测的行为,需要慎之又慎。限制:由于reinterpret_cast几乎不进行类型检查,使用不当很容易导致程序出现未定义行为,如访问非法内存地址、破坏对象的结构等。因此,在使用时需要非常谨慎,并且要对涉及的类型的底层内存布局和表示有深入的理解。
5. 区别总结:(1)静态转换是最常用的转换方式,主要用于非多态类型的转换。(2)动态转换用于在类继承体系中进行安全的向下转型,执行运行时类型检查。(3)常量转换用于添加或删除类型的const属性,但使用时要小心,避免修改应为常量的对象。(4)重新解释转换提供了最低级别的转换方式,只是重新解释内存中的位模式,使用时必须格外小心以避免未定义行为。
Unity/UE虚幻引擎学习,咨询「字符无限科技」17898808287(同微)