You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++使用抛异常的自定义构造函数创建对象数组的异常处理

核心问题说明

你当前的写法无法实现单元素异常捕获的核心原因是:C++ 数组的花括号初始化列表是一个原子性的整体初始化流程,所有元素的构造逻辑同属一个执行上下文,只要任意元素构造抛出异常,就会直接中断整个初始化流程,已经构造完成的前序元素会被自动析构,无法在初始化列表内为单个元素的构造单独套异常捕获逻辑。

另外你的代码存在一处会导致逻辑完全失效的判断错误:strcmp 函数在两个字符串相等时返回0,你当前的异常判断条件写反了:

// 原错误逻辑:航段匹配时反而抛出异常
if (!strcmp(r.legs.back()->endCity, l.startCity)) {
    throw "Cities dont match!";
}
// 修正后逻辑:航段不匹配时抛出异常
if (strcmp(r.legs.back()->endCity, l.startCity) != 0) {
    throw "Cities dont match!";
}
可行实现方案

由于你的Route对象存在链式依赖(后一个路径必须基于前一个构造完成的路径对象生成),不要使用静态数组一次性初始化,改用std::vector<Route>作为存储容器,逐个构造元素,每一步构造单独包裹异常捕获逻辑即可:

#include <vector>
#include <iostream>
// 其余依赖的头文件和类定义保持不变

int main() {
    // 假设legArray是已经完成初始化的长度为10的Leg数组
    std::vector<Route> routes;

    // 单独处理第一个路径元素的构造和异常捕获
    try {
        routes.emplace_back(legArray[0]);
    } catch (const char* err_msg) {
        std::cout << "首段路径构造失败: " << err_msg << std::endl;
        return 1;
    }

    // 循环构造后续路径,每一步单独捕获异常
    for (size_t i = 1; i < 10; ++i) {
        try {
            routes.emplace_back(routes.back(), legArray[i]);
        } catch (const char* err_msg) {
            std::cout << "第" << i + 1 << "段路径构造失败: " << err_msg << std::endl;
            // 可根据业务需求选择break终止,或做其他错误处理
            break;
        }
    }

    // 输出所有构造成功的路径
    for (const auto& route : routes) {
        route.output();
    }

    return 0;
}
方案优势
  • 异常捕获粒度精确到单段路径构造,某一段构造失败不会影响之前已经生成的合法路径对象
  • 由vector自动管理内存,不需要手动计算数组长度,不会出现数组初始化不完全的野值问题
  • 逻辑扩展性更强,后续增减航段数量不需要修改数组初始化的长列表,只需要调整循环边界即可

优化提示:直接抛出const char*类型字符串作为异常不是C++的最佳实践,建议改为抛出标准库异常类型,例如std::runtime_error,可以更规范地携带错误信息,也能避免异常类型匹配混乱的问题。

内容的提问来源于stack exchange,提问作者Chase Nagle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 20:57:21