深入理解C++ 类型转换<三>const_cast

const_cast 是 C++ 中四种命名的强制类型转换之一(另外三种是 static_cast、dynamic_cast 和 reinterpret_cast)。它的唯一职责是添加或移除变量的 const(或 volatile)限定符。它不能改变对象的类型,也不能做其他任何转换。

语法

const_cast<new_type>(expression)

其中 new_type 必须是指针或引用类型,且与 expression 的类型在去除 const/volatile 后必须一致。

主要用途
  • 移除 const (最常见):将 const T* 转为 T*,或 const T& 转为 T&,从而允许修改原本只读的对象(但前提是对象本身不是常量)。

  • 添加 const (较少用):将 T* 转为 const T*,或 T& 转为 const T&,用于重载决议或接口适配。

重要注意事项
  • 未定义行为(UB) :如果用 const_cast 移除一个真正 const 对象 的常量性并试图修改它,则行为是未定义的(程序可能崩溃或产生不可预测结果)。只有当一个对象本身不是 const(例如栈上的非 const 变量),但被一个 const 指针或引用指向时,才可以通过 const_cast 安全地修改它。

  • 只能用于指针或引用:不能直接对对象本身使用,只能对指针或引用。

  • 不能改变底层类型 :例如不能将 int* 转为 char*,那是 reinterpret_cast 的工作。

  • 风险提示 :滥用 const_cast 会破坏 const 正确性,增加代码维护难度。它通常用于与遗留 C 库交互,或解决设计上的妥协,应尽量避免。

例子1: 安全使用

cpp 复制代码
#include <iostream>

int main() {
    int value = 42;                     // 非 const 对象
    const int* const_ptr = &value;      // const 指针指向它

    // 通过 const_cast 移除 const,得到可修改的指针
    int* mutable_ptr = const_cast<int*>(const_ptr);
    *mutable_ptr = 100;                 // 安全,因为 value 本身不是 const

    std::cout << "value = " << value << std::endl;  // 输出 100
    return 0;
}

例子2:不安全使用(对象本身是常量)

cpp 复制代码
#include <iostream>

int main() {
    const int const_value = 42;         // 真正的 const 对象
    const int* const_ptr = &const_value;

    // 移除 const 并尝试修改
    int* mutable_ptr = const_cast<int*>(const_ptr);
    *mutable_ptr = 100;                 // 未定义行为!可能崩溃

    std::cout << "const_value = " << const_value << std::endl;  // 可能输出 42 或 100,或崩溃
    return 0;
}

例子3:添加 const 的例子(少见)

cpp 复制代码
#include <iostream>

void print(const int* p) {
    std::cout << *p << std::endl;
}

int main() {
    int value = 42;
    int* p = &value;
    // 添加 const,使非常量指针可以传递给期望 const 指针的函数
    print(const_cast<const int*>(p));   // 也可以隐式转换,此处仅演示
    return 0;
}
相关推荐
kiracrimson2 分钟前
STL:List的使用和模拟实现
开发语言·c++·list
二十七日秋9 分钟前
算法刷题笔记「Day 1|四道 OJ 入门题里的深坑」
c语言·汇编·数据结构·c++·笔记·python·算法
流年如夢31 分钟前
继承与多态_继承篇
c++·继承·面向对象·c++进阶
北冥you鱼38 分钟前
Go 语言 GORM 使用 Preload:从关联查询到嵌套预加载的完整实践
开发语言·jvm·golang
沫璃染墨1 小时前
从零入门计算机网络系列(十):HTTP协议进阶——从资源路径解析到状态码与请求头详解
linux·运维·服务器·网络·c++·http
dingzd951 小时前
TikTok账号登录态失效的Cookie字段排查路径
开发语言·php·跨境电商·营销策略
曹牧1 小时前
C#:The operation has timed out
开发语言·c#
xiaoye-duck1 小时前
《C++ 工具库实战》高性能日志 spdlog:从基础使用到工程化封装
c++·第三方库
你看我名字1 小时前
数眼智能 Search + Reader 实战:联网问答怎样避免“搜到了,却引用错了”
android·java·开发语言
小嘉丶学长1 小时前
Day13 · 列表与元组
linux·运维·服务器·开发语言·python