C++ 中,有四种主要的类型转换操作符,用于在类型之间进行明确的类型转换。使用 reinterpret_cast 要特别小心,容易引发未定义行为。dynamic_cast 会增加一定运行时开销,但提供类型安全。const_cast 只能用于移除在原始类型中添加的 const,否则行为未定义。推荐优先使用 static_cast 和 dynamic_cast,避免使用 C 风格 (Type) 转换。

1、static_cast

编译时类型检查的显式转换,可用于基本类型之间的转换(如 intfloat),类层次结构中的向上转换(派生类指针转为基类指针),类层次结构中合法的向下转换(无虚函数时,需确保安全)。

#include<iostream>
using namespace std;

int main() {
    float f = 3.14;
    int i = static_cast<int>(f);  // 显式类型转换 float -> int

    std::cout << "原始 float 值: " << f << std::endl;
    std::cout << "转换后的 int 值: " << i << std::endl;

    return 0;
}

2、dynamic_cast

用于类层次中具有虚函数的类型之间的转换,安全的向下转换(基类转派生类)会在运行时检查类型,通常用于多态时判断实际对象类型。如果转换失败,返回 nullptr(指针)或抛出 bad_cast(引用)。

#include<iostream>
using namespace std;

class Base {
public:
    virtual void foo() {
        std::cout << "Base::foo()" << std::endl;
    }
};

class Derived : public Base {
public:
    void foo() override {
        std::cout << "Derived::foo()" << std::endl;
    }

    void bar() {
        std::cout << "Derived::bar()" << std::endl;
    }
};

int main() {
    Base* b = new Derived();  // 基类指针指向派生类对象

    // 使用 dynamic_cast 尝试将 Base* 转换为 Derived*
    Derived* d = dynamic_cast<Derived*>(b);

    if (d != nullptr) {
        std::cout << "转换成功,调用 Derived 成员函数:" << std::endl;
        d->foo();  // 调用重写后的 foo()
        d->bar();  // 调用派生类特有的函数
    } else {
        std::cout << "转换失败" << std::endl;
    }

    delete b;
    return 0;
}

3、const_cast

用于移除或添加 constvolatile 限定符,常用于需要调用非 const 函数的情况下绕过 const 限定。去除 const 并修改值是未定义行为,除非原始对象本身不是 const

#include<iostream>
using namespace std;

void modify(int* p) {
    *p = 10;  // 修改指针指向的值
}

int main() {
    const int x = 5;

    std::cout << "原始 x = " << x << std::endl;

    // 尝试通过 const_cast 去除 const 并修改 x
    modify(const_cast<int*>(&x));  // ⚠️ 危险:修改 const 对象,未定义行为

    std::cout << "修改后 x = " << x << std::endl;

    return 0;
}

4、reinterpret_cast

执行极端的低层次转换,例如指针类型之间、整数与指针之间,不做任何类型检查,极其危险。仅在对底层表示有绝对控制时使用。错误使用会导致严重错误或崩溃。

#include <iostream>
using namespace std;

int main() {
    int i = 65;  // 十进制 65 = 0x41,ASCII 是 'A'
    char* p = reinterpret_cast<char*>(&i);  // 将 int 指针转换为 char 指针

    // 输出 int 的原始值
    cout << "int i = " << i << endl;

    // 输出 int i 的每个字节的值(以十六进制)
    cout << "Bytes of i in memory:" << endl;
    for (size_t j = 0; j < sizeof(int); ++j) {
        printf("Byte %zu: 0x%02x (char: %c)\n", j, static_cast<unsigned char>(p[j]),
               isprint(p[j]) ? p[j] : '.');
    }

    return 0;
}

5、四种类型转换及使用场景

类型转换

说明

使用场景

static_cast

编译期类型转换,用于基本类型转换、指针/引用的上行转换等

类型安全转换,如

intfloat,子类指针转父类指针

dynamic_cast

运行时类型检查的转换,用于支持多态的指针或引用转换

安全向下转型(如父类转子类),需有虚函数(RTTI)

const_cast

用于去除或添加

constvolatile 限定符

去除对象的只读属性,如传给只能接收非常量引用的 API

reinterpret_cast

强制的二进制重解释转换

指针或整数之间的底层转换,如函数指针转换,但非常危险

推荐文档