Visual C++抛出异常时不使用new关键字的正确写法是什么?
关于C++自定义异常抛出方式的说明
- 首先明确结论:你当前的写法、以及代码分析工具建议的
make_unique方案,都不是C++抛出异常的正确实现方式。 - 你现有代码的问题:
你当前写的throw new CChristianLifeMinistryEntryException(strError);是抛出堆上分配的异常对象指针,会存在两个明显缺陷:- 捕获端必须手动
delete对应指针才能避免内存泄漏,不符合异常处理的便捷性要求 - 如果
new操作时内存分配失败抛出std::bad_alloc,会直接覆盖你原本要抛出的自定义异常,导致业务异常逻辑完全失效
- 捕获端必须手动
- 工具建议的
make_unique方案同样不适用于该场景:make_unique会返回std::unique_ptr智能指针,即使你改成throw std::make_unique<CChristianLifeMinistryEntryException>(strError);,本质还是抛出指针类型,捕获端必须严格匹配std::unique_ptr<CChristianLifeMinistryEntryException>类型才能接住异常,完全不符合C++生态的常规异常使用范式,没有实际工程价值。 - 正确的实现方式:
C++标准的异常抛出逻辑是直接抛出栈上的异常对象值,不需要任何动态分配操作,正确写法如下:
捕获时使用常量引用接收即可:throw CChristianLifeMinistryEntryException(strError);
这种写法既不需要手动管理内存,异常处理完成后对象会自动销毁,也避免了额外的内存分配失败风险,符合C++的异常设计规范。try { // 业务代码 } catch (const CChristianLifeMinistryEntryException& e) { // 异常处理逻辑 } - 关于警告的说明:
代码分析工具之所以给出make_unique的建议,是因为识别到你代码中出现了裸new没有对应的delete,默认按普通堆内存分配场景给出了通用优化建议,但异常抛出属于特殊场景,该推荐并不适用,你只要改成上述抛异常对象值的写法,就能直接消除对应的警告。
内容的提问来源于stack exchange,提问作者Andrew Truckle
相关产品推荐
相关产品推荐

