异常详解(C/C++)

在 C/C++ 中,异常是一种用来报告和处理错误的机制。它允许在错误发生时从当前代码跳出,并将控制权转移到一个专门的异常处理程序,以便处理错误。

1. C 语言异常处理

C 语言本身没有内置的异常处理机制,但可以通过以下方式模拟异常处理:

a. 错误码

通过函数的返回值或全局变量传递错误信息。

#include <stdio.h>

int divide(int a, int b, int *result) {
	if(b==0) return -1;		// 错误码:除以 0
	*result = a / b;
	return 0;				// 成功码
}

int main() {
	int result;
	if(divide(10, 0, &result) == -1) {
		printf("Error: Division by zero\n");
	}
	return 0;
}

b. setjmplongjmp
C 提供的非局部跳转机制可以实现类似异常的行为,但使用复杂且不推荐。

#include <stdio.h>
#include <setjmp.h>

jmp_buf env;

void test() {
	printf("Throwing exception\n");
	longjmp(env, 1);	// 跳转到 setjmp 的位置
}

int main() {
	if(setjmp(env) == 0) {
		test();
	} else {
		printf("Caught exception\n");
	}
	return 0;
}

2. C++ 异常处理

C++ 支持内置的异常处理,语法基于 try-catch 块。

a. 基本语法

#include <iostream>

void divide(int a, int b) {
	if(b==0) {
		throw std::runtime_error("Division by zero");
	}
	std::cout << "Result: " << a / b << std::endl;
}

int main() {
	try {
		divide(10, 0);
	} catch (const std::exception& e) {
		std::cerr << "Error:" << e.what() << std::endl;
	}
	return 0;
}

b. 自定义异常
可以继承 std::exception 来定义自己的异常类型:

#include <iostream>
#include <exception>

class MyException : public std::exception {
public:
	const char* what() const noexception override {
		return "My custom exception";
	}
};

int main() {
	try {
		throw NyException();
	} catch (const MyException& e) {
		std::cout << "Caught: " << e.what() << std::endl;
	}
	return 0;
}

c. 多重捕获
根据异常类型捕获不同的异常:

#include <iostream>

int main() {
	try {
		throw 42;	// 抛出一个整数异常
	} catch (int e) {
		std::cout << "Caught integer: " << e << std::endl;
	} catch (...) {
		std::cout << "Caught unknown exception" << std::endl;
	}
	return 0;
}

d. 异常传播
异常可以跨函数传播,直到被捕获:

#include <iostream>
#include <stdexcept>

void funcA() {
	throw std::runtime_error("Error in funcA");
}

void funcB() {
	funcA();
}

int main() {
	try {
		funcB();
	} catch (const std::exception& e) {
		std::cout << "Caught exception:" << e.what() << std::endl;
	}
	return 0;
}

3. 异常相关注意事项

a. noexcept 关键字
C++ 11 引入了 noexcept,用于指定函数是否可能抛出异常。

void func() noexcept {
	// 保证不会抛出异常
}

b. 异常安全性
确保在异常发生时,资源(如内存、文件句柄)能正确释放。可通过 RAII (资源获取即初始化)模式实现。

#include <iostream>
#include <memory>

void func() {
	std::unique_ptr<int> p(new int(10));	// 自动释放
	throw std::runtime_error("Error");
}

int main() {
	try {
		func();
	} catch (const std::exception& e) {
		std::cout << "Caught:" << e.what() << std::endl;
	}
	return 0;
}

c. 性能开销
C++ 异常的使用会增加代码大小,且运行时可能存在性能开销。应避免在性能敏感的代码中频繁抛出异常。

d. 不建议滥用异常
异常用于处理不可预期的错误,不应用于常规流程控制。

通过正确使用异常处理机制,可以提升程序的鲁棒性和可维护性。根据场景选择合适的策略(如 C 的错误码或 C++ 的 try-catch)可以有效地管理错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值