[Cpp基础] [06] 强制类型转换

Last Updated on 2022年9月28日

  • C++风格的类型转换有四种,每个都有特定的应用场合.转换可以分为隐式或显式的,显式转换也被称为强制类型转换.
    • 隐式类型转换语义上只能对应static_cast或const_cast二者其一.
  • 规定:仅有xxx_cast<TYPE &>(var)整体可以作为左值,其他情况转换得到的都是右值临时对象。

强制类型转换

const_cast

  • const_cast是只用于处理const相关的类型转换,主要是移除const(加const完全可以用隐式转换), const_cast只有向引用/指针的转换有实际意义.
const T c_obj;
const T * p_c_obj=&c_obj;
const T * const cp_c_obj=p_c_obj;
T& wobj=const_cast<T&>(c_obj);//通过引用消const
T * p_wobj=const_cast<T *>(p_c_obj);//消去指向对象的const
const T * & p_c_obj2=const_cast<const T * &>(cp_cobj;)//消去指针自身的const  

static_cast

  • static_cast只用于处理编译期(静态)兼容类型间的类型转换,也就是说,dest类型必须支持从src类型构造.
    • static_cast无法获得运行时信息,只会进行普通的编译期检查.
    • 大部分内置数值类型之间都有预定义好的类型转换方法,彼此是兼容的.(截断/提升等)
    • void *指针和任意指针类型之间都是按照reinterpret的形式兼容的.
  • 原则上,const相关的转换只能由const_cast处理,但是有的编译器可能也会允许static_cast做这些工作

dynamic_cast

  • dynamic_cast只用于处理运行期(动态)类型转换.
    • 只有多态类型有动态类型转换(必须要有vptr,因为运行期类型信息存储在vtable中).
    • 类型转换在运行期执行,如果转换失败,会抛出异常或者返回null指针.
    • 对于非多态类型,typeid()总是获得其静态信息.对于多态类型typeid()可以在运行期获得对象类型.
class A{virtual ~A(){}};
class B:public A{};
void f(A * pA){
    B * pB1=static_cast<B *>(pA);//静态转换,由用户保证pA一定指向一个B型实例
    B * pB2=dynamic_cast<B *>(pA);//动态转换,如果运行时pA指向的不是B型对象,就会报错.
}

reinterpret_cast

  • reinterpret_cast只用于内置数值类型,保证转换前后的二进制值一致.
    • 尤其是指针间的转换.用于保证转换前后的内存数值绝对相同.例如,若C同时继承自A和B,则通过static_cast/dynamic_castC * obj向基类Bcast时,编译器会修改指针指向的地址,这种行为可以由reinterpret_cast抑制.