强类型包装
距离和时长都能用 double 保存,但把 100 米当成 9.58 秒传下去时编译器毫无察觉——它只看到两个 double。强类型包装用轻量结构体给基础值加上领域含义,让“不该混用”变成编译错误。本章沿用语言基础的聚合与值语义,不引入新的语言机制。
包装类型
strong-types.cpp
// 强类型包装示例:用两个包装类型区分距离与时长。
#include <iostream>
struct Meters {
double value{0};
};
struct Seconds {
double value{0};
};
int main() {
Meters distance{100.0};
Seconds duration{9.58};
// distance 与 duration 类型不同,互相赋值会被编译器拒绝
std::cout << "距离: " << distance.value << " 米\n";
std::cout << "时长: " << duration.value << " 秒\n";
return 0;
}取用数值时写出 .value,类型本身挡住了单位混用。这层小小的摩擦就是包装的成本,也是它换来的检查。
包装的边界
普通聚合包装依赖约定:成员公开,Meters{9.58} 仍能凭空构造,杜绝误用需要构造函数与不变量,留待自定义类型章节。取值封闭的领域值(方向、状态、档位)直接用 enum class。
常见错误
用注释区分单位
double distance; // 米 依赖读代码的人记住单位,复制粘贴时约束就丢了,包装让编译器参与检查。
处处拆包取值
计算始终在同类间进行时,逻辑先留在包装类型内部(需要成员函数,留给自定义类型章节),不在调用点反复写 .value。
自测问题
distance = duration;为什么通不过编译?查看答案
Meters与Seconds是两个独立类型,之间没有定义转换,类型系统因此拦下了单位混用。普通 struct 包装能防止的误用与防不了的误用各是什么?
查看答案
能防止不同包装类型之间的赋值与传参混用,不能防止凭空构造一个不合理的值。更强的保证需要构造函数与不变量。
本章回顾
你能用轻量包装区分同底层类型的领域值,也知道它的边界。完整示例见 strong-types.cpp。