static_cast:
任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_ cast。强制类型转换告诉程序的读者和编译器:我们知道并且不在乎潜在的精度损失。
如果编译器发现一个较大的算术类型试图赋值给较小的类型,就会给出警告信息;但是当我们执行了显式类型转换,警告就关闭了。
static_ cast 对于编译器无法自动执行的类型转换也非常有用。例如,我们可以使用static_ cast 找回存在于void*指针中的值:
dynamic_cast:
dynamic_cast在C++中主要应用于父子类层次结构中的安全类型转换。它在运行时执行类型检查,因此相比于static_cast,它更加安全。
当需要将基类指针或引用转换为派生类指针或引用时,dynamic_cast可以确保类型兼容性。
如果转换失败,dynamic_cast将返回空指针(对于指针类型)或抛出异常(对于引用类型)。
处理多态对象时,dynamic_cast
可以用来确定对象的实际类型
dynamic_cast的底层原理依赖于运行时类型信息(RTTI, Runtime Type Information)。
C++编译器在编译时为支持多态的类生成RTTI,它包含了类的类型信息和类层次结构。
我们都知道当使用虚函数时,编译器会为每个类生成一个虚函数表(vtable),并在其中存储指向虚函数的指针。伴随虚函数表的还有 RTTI(运行时类型信息)。
dynamic_cast的工作原理的简化描述:
首先,dynamic_cast通过查询对象的 vptr 来获取其RTTI(这也是为什么 dynamic_cast 要求对象有虚函数)
然后,dynamic_cast比较请求的目标类型与从RTTI获得的实际类型。如果目标类型是实际类型或其基类,则转换成功。
如果目标类型是派生类,dynamic_cast会检查类层次结构,以确定转换是否合法。如果在类层次结构中找到了目标类型,则转换成功;否则,转换失败。
当转换成功时,dynamic_cast返回转换后的指针或引用。
如果转换失败,对于指针类型,dynamic_cast返回空指针;对于引用类型,它会抛出一个std::bad_cast异常。
因为dynamic_cast依赖于运行时类型信息,它的性能可能低于其他类型转换操作(如static_cast),static 是编译器静态转换,编译时期就完成了。
const_cast:
const_cast <new_type> (expression) new_type 必须是一个指针、引用或者指向对象类型成员的指针。const_ cast只能改变运算对象的底层const。(也就是指针所指向的对象的常量或非常量属性,而不能改变指针的常量或非常量属性)
对于将常量对象转换成非常量对象的行为,我们一般称其为“ 去掉const性质(cast away the const)”。一旦我们去掉了 某个对象的const性质,编译器就不再阻止我们对该对象进行写操作了。如果对象本身不是一个常量,使用强制类型转换获得写权限是合法的行为。然而如果对象是一一个常量, 再使用const_ cast 执行写操作就会产生未定义的后果。
reinterpret_cast:
reinterpret_ cast 通常为运算对象的位模式提供较低层次上的重新解释,
仅仅是重新解释底层比特(也就是对指针所指向的那片比特位换个类型做解释),而不进行任何类型检查。