ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

C++异常处理

2026/8/11 22:44:33 拓冰建站 浏览量
C++异常处理

C++异常处理

错误

明显的,比如代码不规范,编译错误、头文件引用错误、文件编码错误

异常

程序运行之后,由内存、硬盘、操作系统、网络出现的意外。

C语言怎么处理?

断言

assert判断指针不为空。条件不成立则abort终止程序

assert != NULL;

返回errno错误号

errno.h

dup:复制文件描述符,返回最小可用的新 fd

dup2:强制复制到指定的新 fd(常用作重定向)

int fp = open("a.txt",O_RDONLY); :打开文件,返回文件描述符(fd),失败返回-1

if (fp<2){perror("open");} :打开文件错误信息

int fp = open("a.txt",O_RDONLY); :打开文件,返回文件描述符(fd),失败返回-1

if (fp<2){char * err =strerr(errno);} :显示错误信息(string.h)

错误日志文件

int efd = open("error.log"); ----stderr文件号2

dup2(efd,2);

C++异常机制

简述异常机制

尝试捕获异常,并处理。 ---- try{...}catch(异常类型 对象名){...}

通过判断的方式,抛出异常

编写步骤

throw:抛出异常

语法:

throw 变量/对象/数据;

变量的数据类型 ----任意类型或类

对象的类型 ----任意类型或类

try:尝试捕获

语法:

try{可能存在异常的语句; }

catch:捕获并处理异常

语法:

catch(异常类型 对象/变量){处理异常语句; }

异常被处理之后,则不会向上抛出

void show(char* s) { //assert(s != NULL); if (s == NULL)throw"空指针异常"; s[0] = 'a'; cout << s<<endl; } int main() { cout << "--test error--" << endl; try {//尝试捕获异常 //show(const_cast<char*>("hi,disen!")); char* info = new char[32] {"good,disen!"}; show(info); show(nullptr); } catch(const char* err){ cerr << err << endl;//错误输出 } }

异常处理中的栈捕获(栈对象的解旋)

抛出异常对象时,临时对象存储到异常栈中。抛出异常对象是局部对象时,则执行拷贝构造,在异常栈中。

捕获到异常对象:从异常栈中查找到了。

如果是以非引用的方式,则会从异常栈中拷贝过来,异常处理完场之后,则会释放对象空间。

如果是以引用方式,引用的是栈中的异常对象,不会拷贝。

设计异常类的建议

具有派生体系时, 基类引用的捕获放在最后面。

class BaseException { private: string msg; public: BaseException(const string& msg) :msg(msg) {} virtual string error() { return msg; } }; class DivByZeroException :public BaseException { public: DivByZeroException():BaseException("除数为0"){} }; class NullPointException :public BaseException { public: NullPointException() :BaseException("空指针") {} }; class TimeoutException : public BaseException { private: int timeout; public: TimeoutException(int timeout) : BaseException("连接超时:"), timeout(timeout) {} string error()override { char buf[128] = ""; sprintf_s(buf, "%s %d", BaseException::error().c_str(), timeout); return string(buf); } }; void test1() { cout << "test1 throw NullPointExcepyion" << endl; throw NullPointException(); } void test2() { cout << "test2 throw TimeoutException" << endl; throw TimeoutException(100); } void test3() { cout << "test3 throw DivByZeroException" << endl; throw DivByZeroException(); } int main() { try { //test2(); test3(); } catch (NullPointException& e) {//异常类的基类引用,体现多态性 cout << "NullPointException&:" << e.error() << endl; } catch (TimeoutException& e) {//异常类的基类引用,体现多态性 cout <<"TimeoutException&:" << e.error() << endl; } catch (BaseException& e) {//异常类的基类引用,体现多态性 cout << "BaseException&:" << e.error() << endl; } return 0; }

C++异常体系

C++ 异常是树形继承体系,所有异常的最终基类只有一个:std::exception

整个体系分为两大分支:

  1. 逻辑错误:代码写错、参数错、前提不满足(程序可避免)
  2. 运行时错误 :运行时环境问题、外部资源失败(程序无法避免

bad_alloc:new 分配内存失败

bad_cast:dynamic_cast 转换失败

bad_typeid:typeid 空指针

bad_exception:异常抛出异常

C++11中的noexcept

关键字:noexcept

告诉编译器:这个函数绝对不会抛异常。

如果函数声明了 noexcept,内部却 throw 了,程序会直接终止,不会进入 catch,直接崩溃。

最佳应用位置

1.构造函数

2.拷贝构造

3.getter相关的成员函数

void test3(int v) noexcept{ //runtime_error运行时异常 //bad_exception错误的 if (v == -1)throw out_of_range("v下标越界"); }