0

0

C++如何实现自定义异常类?(继承std::exception)

冰火之心

冰火之心

发布时间:2026-02-19 14:54:45

|

749人浏览过

|

来源于php中文网

原创

必须为自定义异常显式声明虚析构函数并用成员std::string存储消息,否则用基类指针捕获时会资源泄漏或what()返回悬空指针;优先使用std::runtime_error等标准异常类。

c++如何实现自定义异常类?(继承std::exception)

为什么继承 std::exception 不能只重写 what()

因为 std::exceptionwhat()virtual const char*,但它的析构函数不是 virtual —— 这意味着如果你用基类指针捕获派生异常对象,而派生类有自定义成员(比如 std::string),析构时会不调用派生类析构函数,导致资源泄漏或未定义行为。

实操建议:

立即学习C++免费学习笔记(深入)”;

  • 必须显式声明 virtual ~MyException() noexcept = default;(C++11 起推荐加 noexcept
  • 不要在 what() 返回局部变量地址(比如临时 std::string::c_str()),否则返回的指针可能悬空
  • 典型错误现象:std::terminate 被调用、程序崩溃、what() 返回乱码或空字符串

std::runtime_error 和手写继承 std::exception 哪个更稳妥?

优先用 std::runtime_error 或其兄弟类(如 std::logic_error),它们已正确实现虚析构、持有 std::string 并安全返回 c_str()。自己从 std::exception 派生仅在需要独特类型层级(比如想被 catch (const MyDomainError&) 精确捕获)时才必要。

实操建议:

立即学习C++免费学习笔记(深入)”;

  • 如果只是带消息的异常,直接用 throw std::runtime_error("bad file format");
  • 如果需要自定义类型 + 消息 + 额外字段(如错误码 int code_),再继承 std::exception
  • 注意:所有标准异常类(包括 std::runtime_error)都继承自 std::exception,所以 catch (const std::exception&) 仍能兜底

如何让自定义异常支持 std::string 消息且避免内存问题?

关键不是“存不存 std::string”,而是“怎么返回 const char*”。不能返回局部 std::stringc_str(),也不能返回堆分配后忘了释放的指针。

Ink For All
Ink For All

AI写作和营销助手,精心设计的 UI

下载

实操建议:

立即学习C++免费学习笔记(深入)”;

  • 在类内持有一个 std::string 成员(如 std::string msg_;),在构造时初始化它
  • what() 直接返回 msg_.c_str() —— 因为 msg_ 是对象生命周期内的成员,指针有效
  • 不要手动 new char[] 拼接字符串;也不要返回 std::to_string(x).c_str() 这种临时对象的指针
  • 示例片段:
    class FileOpenError : public std::exception {
        std::string msg_;
    public:
        explicit FileOpenError(const std::string& path) 
            : msg_("Failed to open: " + path) {}
        const char* what() const noexcept override { return msg_.c_str(); }
        virtual ~FileOpenError() noexcept = default;
    };

抛出和捕获时的类型切片风险

如果抛出的是临时对象(throw MyException("x");),而你用非引用方式捕获(catch (MyException e)),会触发拷贝构造 —— 如果没定义或禁用了拷贝,编译失败;如果拷贝了但基类析构不虚,就切片掉派生部分。

实操建议:

立即学习C++免费学习笔记(深入)”;

  • 始终用 const 引用捕获:catch (const MyException& e)
  • 确保自定义异常类可拷贝(默认生成即可),除非你明确禁用并改用智能指针包装(极少需要)
  • 检查编译器警告:Clang/GCC 加 -Wcatch-value 会提醒你捕获方式可能导致切片

实际写的时候,最常被忽略的是虚析构和 what() 返回值的生命周期绑定。这两点一错,异常看起来“抛出了”,但捕获后 e.what() 不是空就是乱码,调试时容易绕远路。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

770

2023.08.02

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

865

2023.07.31

python中的format是什么意思
python中的format是什么意思

python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

450

2024.06.27

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

547

2023.09.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

573

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

216

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1553

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

640

2023.11.24

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

660

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 9.7万人学习

C 教程
C 教程

共75课时 | 4.8万人学习

C++教程
C++教程

共115课时 | 18.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号