C++中的算术转换、其他隐式类型转换和显示转换详解

C++中的类型转换(Type Conversion)是指将一个数据类型的值转换为另一个数据类型的过程,主要包括:


一、算术类型转换(Arithmetic Conversions)

算术类型转换通常发生在算术运算或比较中 ,称为**"标准转换"(standard conversion),遵循一定的提升规则(promotion rules)**。

转换规则(简化版):

  1. boolint
  2. 整型提升:charshortint
  3. 两个操作数不同类型时:
    • 若一个为浮点型,另一个为整型 → 整型转换为浮点型
    • 若一个为double,另一个为floatfloat 转为 double
    • 若一个为unsigned且它的值不能用int表示 → int转为unsigned
    • 否则,unsigned提升优先级高于signed

示例:

cpp 复制代码
#include <iostream>
int main() {
    char c = 100;
    int i = 200;
    float f = 1.5f;
    double d = 3.14;

    auto result1 = c + i;   // char → int,结果是 int
    auto result2 = i + f;   // int → float,结果是 float
    auto result3 = f + d;   // float → double,结果是 double

    std::cout << "result1: " << result1 << "\n"; // 300
    std::cout << "result2: " << result2 << "\n"; // 201.5
    std::cout << "result3: " << result3 << "\n"; // 4.64
}

二、其他隐式类型转换(Implicit Conversion)

这是 编译器自动完成 的转换,也叫类型提升(promotion)或类型协同(coercion)

常见的隐式转换:

类型 转换方向 示例
数值型 更大/更精度的数值 intdouble
指针类型 派生类 → 基类 Derived*Base*
空指针 nullptr → 任何指针类型 nullptr → int*
数组/函数 → 指针 int arr[]int*

示例:

cpp 复制代码
void printDouble(double d) {
    std::cout << "Double: " << d << "\n";
}

class Base {};
class Derived : public Base {};

int main() {
    int i = 42;
    printDouble(i); // int → double(隐式)

    Derived d;
    Base* bptr = &d; // Derived* → Base*(隐式)
}

三、显示类型转换(Explicit Conversion / Cast)

你可以显式地指示编译器进行类型转换,有四种标准C++风格的转换方式(推荐),以及一个C风格的转换(不推荐)。

四种C++显式转换:

  1. static_cast<T>(expr)

    ➤ 用于基本类型之间转换指针/引用向上转换等安全转换。

  2. dynamic_cast<T>(expr)

    ➤ 用于带有虚函数的多态类 之间的安全运行时类型检查和向下转换

  3. const_cast<T>(expr)

    添加或去除const、volatile限定符,常用于函数参数处理。

  4. reinterpret_cast<T>(expr)

    不安全但允许的位级别转换,如指针与整数之间转换。

  5. (T)expr ------ C风格强制转换

    ➤ 组合了上述所有功能,不安全不透明,不推荐使用


示例:

cpp 复制代码
#include <iostream>
class Base { public: virtual ~Base() {} };
class Derived : public Base { public: void say() { std::cout << "Derived\n"; } };

int main() {
    int i = 100;
    double d = static_cast<double>(i);  // int → double

    Base* b = new Derived();
    Derived* dptr = dynamic_cast<Derived*>(b);  // 安全向下转型
    if (dptr) dptr->say();

    const int ci = 42;
    int* p = const_cast<int*>(&ci);  // 去除 const 限定

    void* vptr = reinterpret_cast<void*>(p); // int* → void*
    int* iptr = reinterpret_cast<int*>(vptr); // void* → int*

    delete b;
}

四、总结对比表:

转换类型 触发方式 安全性 用途/说明
算术转换 自动 安全 数值运算中的标准提升
隐式转换 自动 通常安全 函数调用/指针/基本类型提升
static_cast 显式 安全 编译期可检查的转换,如 int→float,向上转型
dynamic_cast 显式 安全 多态类型的运行时向下转型
const_cast 显式 有风险 去除 const/volatile
reinterpret_cast 显式 不安全 位级别转换,极端情况用
C风格强制转换 显式 不推荐 混合多个C++转换,缺乏类型安全

五、综合例子

下面是一个C++ 示例工程,通过一个模拟图形系统的类结构,演示了**各种类型转换(隐式、算术、显示转换)**的组合使用。代码里有注释,方便理解每一种转换在什么时候触发、为什么安全或者不安全。

定义 shape.h图形类头文件内容如下:

cpp 复制代码
#pragma once
#include <iostream>
#include <string>

class Shape {
public:
    virtual ~Shape() {}
    virtual void draw() const;
};

class Circle : public Shape {
public:
    Circle(double r);
    void draw() const override;
    double getRadius() const;
private:
    double radius;
};

class Rectangle : public Shape {
public:
    Rectangle(int w, int h);
    void draw() const override;
    int area() const;
private:
    int width, height;
};

// 模拟图形渲染系统的底层资源对象
struct RenderHandle {
    void* data;
};

RenderHandle createHandle(int id);

shape.cpp 图形类实现如下:

cpp 复制代码
#include "shape.h"

void Shape::draw() const {
    std::cout << "Drawing Shape\n";
}

Circle::Circle(double r) : radius(r) {}
void Circle::draw() const {
    std::cout << "Drawing Circle with radius: " << radius << "\n";
}
double Circle::getRadius() const {
    return radius;
}

Rectangle::Rectangle(int w, int h) : width(w), height(h) {}
void Rectangle::draw() const {
    std::cout << "Drawing Rectangle of area: " << area() << "\n";
}
int Rectangle::area() const {
    return width * height;
}

RenderHandle createHandle(int id) {
    RenderHandle h;
    h.data = reinterpret_cast<void*>(id);  // 显式 reinterpret_cast
    return h;
}

main.cpp 主函数演示各种类型转换示例内容如下:

cpp 复制代码
#include "shape.h"
#include <typeinfo>

void printDouble(double d) {
    std::cout << "Double value: " << d << "\n";
}

int main() {
    // 算术类型转换(int → double)
    int i = 42;
    double d = i; // 隐式转换
    printDouble(d); // 参数是 double

    float f = static_cast<float>(i); // 显式 static_cast
    std::cout << "Float from int: " << f << "\n";

    // 基类 → 派生类的动态转换(dynamic_cast)
    Shape* s = new Circle(3.5);
    s->draw();

    if (Circle* c = dynamic_cast<Circle*>(s)) {
        std::cout << "Radius from casted circle: " << c->getRadius() << "\n";
    }

    // const_cast 演示
    const int ci = 100;
    int* modifiable = const_cast<int*>(&ci);
    *modifiable = 999; // 未定义行为,仅演示用
    std::cout << "Modified const int (unsafe!): " << *modifiable << "\n";

    // reinterpret_cast 演示
    int resourceID = 1234;
    RenderHandle h = createHandle(resourceID);
    int recoveredID = reinterpret_cast<int>(h.data);
    std::cout << "Recovered ID from RenderHandle: " << recoveredID << "\n";

    // 隐式派生 → 基类(安全)
    Rectangle rect(10, 20);
    Shape* s2 = &rect;
    s2->draw();  // 虚函数,多态行为

    delete s;
    return 0;
}

示例的演示内容如下:

场景 类型转换 涉及关键字/方式
int → double 算术隐式转换 自动
float ← int 算术显式转换 static_cast
Base* ← Derived* 隐式向上转换 自动
Derived* ← Base* 安全运行时转换 dynamic_cast
const int* ← int* 添加/去除 const const_cast
void* ←→ int 指针/整数转换 reinterpret_cast
Shape 多态行为 虚函数机制 隐式
相关推荐
XINVRY-FPGA2 分钟前
XCZU7EG‑L1FFVC1156I 赛灵思XilinxFPGA ZynqUltraScale+ MPSoC EG
c++·嵌入式硬件·阿里云·fpga开发·云计算·fpga·pcb工艺
_GR1 小时前
2025年蓝桥杯第十六届C&C++大学B组真题及代码
c语言·数据结构·c++·算法·贪心算法·蓝桥杯·动态规划
mahuifa2 小时前
(7)VTK C++开发示例 --- 使用交互器
c++·vtk·cmake·3d开发
光算科技3 小时前
服务器在国外国内用户访问慢会影响谷歌排名吗?
运维·服务器·c++
大炮筒3 小时前
CPPlist初识
数据结构·c++·list
Zfox_5 小时前
Git 进阶之路:高效协作之分支管理
大数据·linux·运维·c++·git·elasticsearch
wenchm5 小时前
细说STM32单片机FreeRTOS任务管理API函数vTaskList()的使用方法
c语言·c++·stm32·单片机·嵌入式硬件
wuqingshun3141595 小时前
蓝桥杯 10.拉马车
数据结构·c++·算法·职场和发展·蓝桥杯·深度优先
不是仙人的闲人6 小时前
算法之动态规划
数据结构·c++·算法·动态规划