C++ 类型转换

A. 隐式标准转换(Standard Conversion Sequence)

  1. 整型提升
cpp 复制代码
char c = 'A';
int  i = c;          // char → int 提升,无警告
std::cout << i;      // 65
  1. 整型 ↔ 浮点
cpp 复制代码
double d = 3;        // int → double
int    n = 3.14;     // double → int,截断为 3
  1. 数组退化(array-to-pointer)
cpp 复制代码
int a[4] = {1,2,3,4};
int* p = a;          // 数组名退化为 int*
  1. 指针转换
cpp 复制代码
int  x = 0;
int* p = &x;
void* pv = p;        // int* → void* 隐式

一句话规则:无需写任何关键字,编译器自动完成;只在"安全"场景下出现。


B. 用户定义转换(User-Defined Conversion)

  1. 转换构造函数
cpp 复制代码
struct Length {
    double m;
    Length(double x) : m(x) {}   // 转换构造
};
Length L = 42.0;     // double → Length,隐式
  1. 转换函数
cpp 复制代码
struct Money {
    double amount;
    explicit operator double() const { return amount; }
};
Money m{100};
double d = static_cast<double>(m);   // 必须显式

一句话规则:把"别的类型→本类型"写成构造函数;把"本类型→别的类型"写成 operator T()。

坑点:explicit 能堵住隐式,但挡不住显式 cast。


C. 继承体系里的三种 cast

  1. 向上转型(Up-cast)
cpp 复制代码
struct Base { virtual ~Base() = default; };
struct Derived : Base {};

Derived d;
Base*   pb = &d;     // 隐式安全
  1. 向下转型(Down-cast)
cpp 复制代码
Base* pb = new Derived;
Derived* pd = dynamic_cast<Derived*>(pb);   // 安全,失败返回 nullptr
  1. 交叉转型(Cross-cast)
cpp 复制代码
struct A { virtual ~A() = default; };
struct B : virtual A {};
struct C : virtual A {};
struct D : B, C {};

D  obj;
B* pb = &obj;
C* pc = dynamic_cast<C*>(pb);  // B→C,成功

一句话规则:

  • 向上永远安全;
  • 向下/交叉用 dynamic_cast,否则 UB。

D. 对象切片(Slicing)

cpp 复制代码
struct Person { std::string name = "base"; };
struct Student : Person { int id = 42; };

Student s;
Person  p = s;      // 只拷贝 Person 部分,id 丢失
std::cout << p.name;   // base

一句话规则:把派生类对象 按值赋给/传参给 基类就会切片,改为指针/引用可避免。


E. 四种显式 cast

  1. static_cast(编译期检查)
cpp 复制代码
int   i = 10;
double d = static_cast<double>(i);
  1. dynamic_cast(运行期 RTTI)
cpp 复制代码
Base* pb = new Derived;
Derived* pd = dynamic_cast<Derived*>(pb);
  1. const_cast(仅改 cv 限定)
cpp 复制代码
const int ci = 5;
int* modifiable = const_cast<int*>(&ci);   // 注意:改值 UB
  1. reinterpret_cast(位级重解释)
cpp 复制代码
int  n = 0x1234;
int* p = &n;
std::uintptr_t v = reinterpret_cast<std::uintptr_t>(p);

一句话规则:

  • 数值/枚举/指针用 static_cast;
  • 跨继承用 dynamic_cast;
  • 去 const 用 const_cast;
  • 位级解释用 reinterpret_cast。

F. 模板与转换(enable_if / concepts)

cpp 复制代码
template<class T>
auto abs_val(T v)
    -> std::enable_if_t<std::is_signed_v<T>, T>
{
    return v < 0 ? -v : v;
}

C++20 Concepts 写法:

cpp 复制代码
template<std::signed_integral T>
T abs_val(T v) { return v < 0 ? -v : v; }

一句话规则:用 type traits 或 concepts 在编译期把"能否转换"写成约束。


G. C++20 bit_cast

cpp 复制代码
float f = 3.14f;
uint32_t u = std::bit_cast<uint32_t>(f);   // 与 memcpy 等效,安全

一句话规则:把 TriviallyCopyable 类型的位模式按字节搬到另一个同样大小的类型,零开销、无 UB。


使用速查表

需求 推荐 禁止
数值互转 static_cast C-style
派生→基类 隐式或 static_cast ---
基类→派生 dynamic_cast static_cast(可能 UB)
去掉 const const_cast reinterpret_cast
位级重解释 bit_cast / reinterpret_cast C-style
模板约束 enable_if / concepts ---

把示例直接拷进小文件即可独立编译运行。

相关推荐
Ai-_Man7 分钟前
Coze扣子还是不可以导出左侧所有对话,只能点进去单条内容导出,方法不对吗?
开发语言·人工智能·ai·小程序·1024程序员节
UIU11414 分钟前
P16237 [蓝桥杯 2026 省 B] 应急布线
数据结构·c++·算法·蓝桥杯
raindayinrain15 分钟前
c++设计模式
开发语言·c++·设计模式
旖旎夜光17 分钟前
LeetCode 315: 算右侧小于当前元素的个数(归并排序) —— 题解
c++·学习·算法·leetcode·排序算法
hiahiahia12323 分钟前
Streaming Model Output
开发语言·前端
D e re k ZH32 分钟前
保序回归:从 PAVA 到可并堆的单调约束优化
c++·算法·数据挖掘·回归·kotlin
青少儿编程课堂33 分钟前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:字典树前缀树与单词检索统计
c++·python·算法·bfs·信息学竞赛
熊猫钓鱼>_>1 小时前
鸿蒙PC高分屏与键鼠交互适配:DPI缩放、右键菜单一次讲清
开发语言·笔记·华为·ai编程·harmonyos·鸿蒙·鸿蒙心迹
octopus_c1 小时前
C++ 运算符重载详解 && 日期类的实现
开发语言·c++
青少儿编程课堂1 小时前
2026蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:堆排序与优先队列解析
c++·python·算法·bfs·信息学竞赛