C++强制类型转换
static_cast
, 类似于c语言中旧式类型转换,可以进行基础类型之间的转换,也可以强转 带有可被单参调用的构造函数的对象 或者 自定义了类型转换操作符的对象, 还可以强转 存有继承类关系的对象之间(基类对象强转为子类对象,或者子类对象强转为基类对象),还可以将 non-const对象转为const对象(反之不行)。
double d = 3.14159265; int i = static_cast<int>(d); class A {}; class B { public: B (A a) {}; }; A a; B b = static_cast<B>(a); class Base {}; class Derived: public Base {}; Base * pb = new Base; Derived * pd = static_cast<Derived *>(pb); //! 虽然可以编译通过,但是运行时很可能出错 Derived * pd_2 = new Derived; Base * pb_2 = static_cast<Base * >(pd_2);
dynamic_cast
, 主要用来在继承体系中的安全向下转型。dynamic_cast能安全地将指向基类的指针转型为指向子类的指针或者引用,并获知是否转型成功。如果转型失败会返回nullptr(转型对象为指针时)或抛出异常(转型对象为引用时)。dynamic_cast会使用运行时信息(RTTI)进行类型检查,所以dynamic_cast会存在效率问题。dynamic_cast只能转型指针或者引用对象。
class Base {}; class Derived: public Base {}; Base * pb = new Base; Derived * pd = dynamic_cast<Derived *>(pb); //! 编译期间报错 error: cannot dynamic_cast 'pb' (of type 'class Base*') to type 'class Derived*' (source type is not polymorphic) Derived * pd_2 = new Derived; Base * pb_2 = static_cast<Base * >(pd_2);
报错这是因为dynamic_cast只有在基类带有虚函数的情况下才允许将基类转换为子类,
class Base { virtual void fun() {} }; class Derived: public Base {}; Base * pb = new Base; Derived * pd = dynamic_cast<Derived *>(pb); //+ pd = nullptr Derived * pd_2 = new Derived; Base * pb_2 = static_cast<Base * >(pd_2);
dynamic_cast也可以在nullptr和其他类型的指针之间相互转换,也可以将指向其他类型的指针转换为 void * 指针,所以可以获取一个对象的内存起始地址:
const void * raw_address = dynamic_cast<const void *>(this);
const_cast
, 唯一作用就是设置或者移除对象的const属性
class A {}; class B {}; A * a = new A; const A * ca = const_cast<const A *>(a); const B * cb = new B; B * b = const_cast<B *>(cb);
reinterpret_cast
, 可以将一个指针转换为任意其它类型的指针,也可以用来将一个指针转换为一个整型(反之亦然)。reinterpret_cast属于低级转型操作符,可以在互不相关的类之间进行指针转换,操作的结果是简单的将一个指针的二进制数据(binary copy)复制到另一个指针,对指针指向的内容不做任何检查或转换。一般情况下,很少用。如果用到,也一定要小心使用。
goudan-er SHARE · CPP
C++