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)复制到另一个指针,对指针指向的内容不做任何检查或转换。一般情况下,很少用。如果用到,也一定要小心使用。

对话与讨论