C++摄氏度转开尔文功能的基础错误处理最优方案咨询
C++ 简单参数校验场景的轻量错误处理方案
原有两种方案各有明显缺陷:
- 直接调用
exit(1)的方案完全剥夺了上层调用方的错误处理权,生产环境中如果该函数被其他模块复用,遇到非法输入直接终止整个程序的行为不可接受 - 异常处理对于这种高频、预期内的参数校验场景存在额外开销,且要求调用方必须捕获异常否则会触发程序终止,确实属于过度设计
以下三种是适合该场景的轻量错误处理方案:
方案1:返回哨兵值
适合业务逻辑简单、函数返回值范围明确的场景
约定一个不可能出现在合法返回结果里的值作为错误标记,调用方拿到返回值后先判断是否为哨兵值即可做对应处理。
对于摄氏度转开尔文的场景,合法返回值必然大于0,可约定返回-1.0作为非法输入的标记:
double ctok(double c) // 摄氏度转开尔文 { if (c <= -273.15) { return -1.0; // 哨兵值,代表输入非法 } return c + 273.15; } int main() { double c = 0; cin >> c; double k = ctok(c); if (k < 0) { cout << "Temp too low." << endl; return 1; } cout << k << endl; return 0; }
优点:实现零额外成本,逻辑简单易懂
缺点:需要调用方知晓哨兵值的约定,若返回值范围覆盖所有double取值则不适用
方案2:返回错误码+输出参数传递结果
适用所有简单函数校验场景,无返回值范围限制
函数返回布尔值代表转换是否成功,转换后的结果通过引用类型的输出参数传递给调用方:
bool ctok(double c, double& k) // 摄氏度转开尔文 { if (c <= -273.15) { return false; } k = c + 273.15; return true; } int main() { double c = 0; cin >> c; double k = 0; if (!ctok(c, k)) { cout << "Temp too low." << endl; return 1; } cout << k << endl; return 0; }
优点:逻辑清晰无歧义,不需要约定哨兵值,兼容所有C++版本
缺点:需要额外定义输出参数,调用方需要先声明变量接收结果
方案3:使用C++17引入的std::optional
类型安全的现代C方案,推荐支持C17的项目使用std::optional<T>类型可以存储T类型的有效值,也可以存储空状态代表无有效值,从语法层面强制调用方做错误判断,避免遗漏:
#include <optional> std::optional<double> ctok(double c) // 摄氏度转开尔文 { if (c <= -273.15) { return std::nullopt; // 空状态代表输入非法 } return c + 273.15; } int main() { double c = 0; cin >> c; auto res = ctok(c); if (!res.has_value()) { cout << "Temp too low." << endl; return 1; } cout << res.value() << endl; return 0; }
优点:类型安全,不需要额外约定,代码可读性高
缺点:仅支持C++17及以上版本标准
内容的提问来源于stack exchange,提问作者jaylse2
相关产品推荐
相关产品推荐

