跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
C++

C++显性契约与隐性规则:类型转换

C++ 类型转换机制包含隐式与显式,提供 static_cast、reinterpret_cast、const_cast、dynamic_cast 等运算符以规避风险。涉及基本类型、继承层级及用户定义转换。RTTI 支持运行时类型识别,通过 typeid 和 dynamic_cast 实现。需注意 const 变量优化导致的寄存器与内存差异,以及向下转型的安全性检查。

BackendPro发布于 2026/3/23更新于 2026/5/45 浏览
C++显性契约与隐性规则:类型转换

关于类型转换,通常是隐式转换或者强制转换,C++ 提供了一些能够显式表示转换的运算符,能够更好的规避一些风险和错误。

1.传统的类型转换

在 C 语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化。

void Test() {
    int i = 1; // 隐式类型转换
    double d = i;
    printf("%d, %.2f\n", i, d);
    int* p = &i; // 显示的强制类型转换
    int address = (int)p;
    printf("%x, %d\n", p, address);
}

转换分为显式和隐式:

  1. 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败
  2. 显式类型转化:需要用户自己处理

然而这两种转换的前提是逻辑相近:

  • 基本类型间的转换(如 int ↔ double)
  • 继承层级中的转换(如子类→父类、父类→子类)
  • 用户定义的转换(如 operator T() 或带参数的构造函数)
string s; vector<int>=(vector<int>) s; // 这种转换就会失败,因为逻辑不相近

对于强制转换还有一种特殊易错的场景。

int main() {
    const int n = 10;
    int* p = (int*)&n;
    (*p)++;
    cout << n << endl;
    cout << *p << endl;
    return 0;
}

无论是有点 C 语言基础的人,甚至是学完 C++ 的初学者,都很容易认为这里的输出结果是:n 为 11,*p 为 11。但是结果并非所愿,输出结果:n 为 10,*p 为 11。

实际上这里涉及到存储规则的问题,因为 是 变量,那么会被识别为一个常变量,可能会是一个经常被使用的值,就把 存入寄存器,把频繁使用的变量的值暂存到寄存器中,这样在后续对该变量的读取操作中,就不需要每次都去内存中读取,直接从寄存器中获取即可,因为寄存器的读写速度比内存快很多。

n
const
n

通常 cout 输出的值都是在内存里读取的,相比寄存器,内存读写速度较慢,但内存容量相对寄存器大很多,大多的代码都是存在这里的。

因此这里输出的 n 是取自内存器,*p 取自内存。

volatile const int n = 10;

volatile 关键字表示该变量的值可能会在程序未明确指定的情况下被改变,编译器不会对其进行优化,即不会被存入寄存器,这样取到的 n 就是内存中及时更新的值。

C 风格的转换格式很简单,但是有不少缺点的:

  1. 隐式类型转化有些情况下可能会出问题:比如数据精度丢失
  2. 显式类型转换将所有情况混合在一起,代码不够清晰

因此 C++ 提出了自己的类型转化风格,注意因为 C++ 要兼容 C 语言,所以 C++ 中还可以使用 C 语言的转化风格。

2.C++强制类型转换

2.1 static_cast

int main() {
    double d = 12.34;
    int a = static_cast<int>(d);
    cout << a << endl;
    return 0;
}

static_cast 需要逻辑上的相近性。

2.2 reinterpret_cast

int main() {
    // 这里使用 static_cast 会报错,应该使用 reinterpret_cast
    // int *p = static_cast<int*>(a);
    int* p = reinterpret_cast<int*>(a);
    return 0;
}

reinterpret_cast 几乎无类型限制,不要求类型相近,可强制转换任意指针或整数类型,但极其危险,可能导致:

  • 违反别名规则(如通过 char* 修改 int)
  • 函数指针转换后调用,引发崩溃
  • 平台依赖(如不同架构的指针大小不同)

2.3 const_cast

void Test() {
    volatile const int a = 2;
    int* p = const_cast<int*>(&a);
    *p = 3;
    cout << a << endl;
}

仅改变类型的 const / volatile 属性,这里用 reinterpret_cast 也不行的,因为 const 的转换是有风险的。

2.4 dynamic_cast

class A {
public:
    virtual void f() {}
};
class B : public A {};

void fun(A* pa) {
    // dynamic_cast 会先检查是否能转换成功,能成功则转换,不能则返回 nullptr
    B* pb1 = static_cast<B*>(pa);
    B* pb2 = dynamic_cast<B*>(pa);
    cout << "pb1:" << pb1 << endl;
    cout << "pb2:" << pb2 << endl;
}

int main() {
    A a;
    B b;
    fun(&a);
    fun(&b);
    return 0;
}

dynamic_cast 用于将一个父类对象的指针/引用转换为子类对象的指针或引用 (动态转换)。

  • 向上转型: 子类对象指针/引用->父类指针/引用 (不需要转换,赋值兼容规则)
  • 向下转型: 父类对象指针/引用->子类指针/引用 (用 dynamic_cast 转型是安全的)

pa 是指向子类对象 B 的,转换可以成功,正常返回地址;pa 是指向父类对象 A 的,转换失败,返回空指针。

🔥值得注意的是: 必须是继承关系中的类,基类必须包含虚函数。

3.RTTI

RTTI: Run-time Type identification 的简称,即:运行时类型识别。

C++ 通过以下方式来支持 RTTI:

  1. typeid 运算符
  2. dynamic_cast 运算符
  3. decltype

目录

  1. 1.传统的类型转换
  2. 2.C++强制类型转换
  3. 2.1 static_cast
  4. 2.2 reinterpret_cast
  5. 2.3 const_cast
  6. 2.4 dynamic_cast
  7. 3.RTTI
  • 💰 8折买阿里云服务器限时8折了解详情
  • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
  • 代充Chatgpt Plus/pro 帐号了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • C++ 从零实现 Json-Rpc 框架:服务端模块划分
  • 人工智能应用工程师(高级)技能体系与课程路径解析
  • Pix4Dmapper 大疆无人机影像数据处理流程
  • 前端项目部署后浏览器报 MIME type text/html 错误原因解析
  • Windows 平台 Visual C++ 14.0 安装与配置实战指南
  • Windows 平台 Visual C++ 14.0 安装与环境配置实战
  • Neo4j Desktop 2.0 安装及自定义路径配置指南
  • APP、Web、H5、iOS 与 Android 的区别及关系
  • cv_resnet50_face-reconstruction 在 Deepfake 检测预处理中的应用
  • 大数据领域 HDFS 在医疗行业的数据存储实践
  • 深入 llama.cpp:llama-server 从命令行到 HTTP Server
  • Spring Boot Web 三大核心交互实战:表单、AJAX 与 JSON
  • 基于 Python 大数据的协同过滤音乐推荐系统
  • 前端实战:如何实现用户上次阅读位置恢复
  • 前端 Canvas 基础绘制与动画交互实战
  • Python 高效开发:uv 安装、配置与最佳实践
  • 解决 Java 编译报错:源发行版 17 需要目标发行版 17
  • Whisper-large-v3 语音识别服务部署与开发实战
  • C++微服务 UserServer 设计与实现
  • Vitis 实战:从零将 AI 模型部署到 FPGA

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online