C/C++学习笔记十一

这篇博客详细介绍了C++中的异常处理机制,包括处理原则、常见异常类型如Bad_area、Range_error、runtime_error等的处理方法。通过示例展示了如何在代码中抛出、捕获和处理异常,以及如何自定义异常类来增强错误处理能力。此外,还提到了类型窄化错误和逻辑错误的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、C++异常机制

1、处理原则

        C++提供了异常机制exception用于处理错误。不能忘记异常:在异常没有得到处理时,程序将终止。每一种错误都可以用异常来报告try catch。

        必须为每一个异常设计处理方式。要处理程序中抛出throw 的每一个异常。错误处理Error handling 从来都不简单。

2、常见异常

(1)错误引元

class Bad_area { }; // 用于从area函数报告错误的类型
// 计算矩形面积;
// 在输出错误引元的情况下抛出一个Bad_area 异常
int area(int length, int width)
{
    if (length<=0 || width <=0) throw Bad_area();
    return length*width;
}
int main(){
try {
    int x= -1;
    int y=2;
    int z= 4;
    //……
    int area1 = area(x,y);
    int area2 = framed_area(1,z);
    int area3 = framed_area(y,z);
    double ratio = area1/area3;
}
catch (Bad_area) {
    cout << "Oops! bad arguments to area()\n";
}
}

(2)越界

        尝试运行下面的程序

vector<int> v(10); // 具有10个int的vector
// 每一个初始化为0
// 引用方式为v[0] .. v[9]
for (int i = 0; i<v.size(); ++i) v[i] = i; // 设置值
for (int i = 0; i<=10; ++i) // 打印10个值(???)
cout << "v[" << i << "] == " << v[i] << endl;

        如果使用了#include "std_lib_facilities.h"、vector的操作符[ ] (下标操作符) 就会报告错误的索引、抛出Range_error 错误、缺省行为会有所差异。

        捕获越界异常

int mainO
{
try {
    vector<int> v; // 一个int类型的vector
    int x;
    while (cin >> x) v.push_back(x); // 设置值
    for (int i = 0; i<=v.size(); ++i) // 打印值
    cout << "v["<< i <<”] == n << v[i] << endl;
} catch (out_of_range_error) {
    cerr << "Oops! Range enor\n";
    return 1;
} catch (…){ // 捕获其他所有异常
    cerr << "Exception: something went wrong\n";
    return 2;
}
}

(3)错误输入

double some_function()
{
double d = 0;
cin>> d;
if (!cin) error("couldn't read a double in 'some_function()' ");
// do something useful
}
void error(string s)
{
throw runtime_error(s);
}
void error(string s1, string s2)
{
throw runtime_error(sl +s2);
}

        捕获异常

int main(){
try {
    // 我们的程序
    return 0; // 0表示成功
}
catch (runtime_error& e) {
    cerr << "runtime error: " << e.what() << '\n ';
    keep_window_openO;
    return 1; // 1表示失败
}
catch ( ... ) {
    cerr << "Oops: unknown exception!\n " ;
    keep_window_open();
    return 2; //2 表示失败
}

 (4)类型窄化错误

        narrow_cast 在std_lib_facililies.h 中定义

int x=2.9;
char c = 1066;
int xl = narrow_cast<int>(2.9); //throws
int x2 = narrow_cast<int>(2.0); // OK
char c1 = narrow_cast<char>(l066); //throws
char c2 = narrow_cast<char>(85); // OK

(5)逻辑错误

int main(){
    vector<double> temps; // 温度
    double temp = 0;
    double sum = 0;
    double high_temp = -1000;
    double low_temp = 1000;
    while (cin>>temp) temps.push_back(temp); // 读入温度
    for (int i = 0; i<temps.size(); ++i) {
    if(temps[i] > high_temp) high_temp = temps[i]; // 找到最高温度
    if(temps[i] < low_temp) low_temp = temps[i]; // 找到最低温度
    sum += temps[i]; // 计算总和
    }
    cout << "High temperature: " << high_temp << endl;
    cout << "Low temperature: " << low_temp << endl;
    cout << "Average temperature: " << sum/temps.size() << endl;
}

二、异常示例

1、引发异常

        由除0的错误导致异常。

#include "stdafx.h"
#include "iostream.h"

int main(int argc, char* argv[])
{
	int nDiv = 100;							//定义一个整型变量,初始化为100
	int nDivisor = 0;							//定义一个整型变量,初始化为0
	int nRet = nDiv / nDivisor;				//进行除法运算
	cout << nRet << endl;					//输出结果
	return 0;
}

2、捕获异常

        异常被捕获,程序并未中断。

#include "stdafx.h"
#include "iostream.h"


int main(int argc, char* argv[])
{
	try										//捕捉异常
	{
		int nDiv = 100;							//定义一个整型变量,初始化为100
		int nDivisor = 0;							//定义一个整型变量,初始化为0
		int nRet = nDiv / nDivisor;				//进行除法运算
		cout << nRet << endl;					//输出结果
	}
	catch(...)									//处理异常
	{
		cout << "产生异常!" << endl;
	}
	return 0;
}

3、抛出异常

        在程序中,异常语句通常出现在try语句块中,当程序运行到throw语句时,后面的代码不会被执行,而是跳到catch语句块中。

#include "stdafx.h"
#include "iostream.h"

int main(int argc, char* argv[])
{
	try
	{
		int nDiv = 100;								//定义一个整数,初始化为100
		int nDivisor = 0;								//定义一个整数,初始化为0
		if (nDivisor <= 0)							//如果除数小于等于0
		{
			throw "除数必须大于0!";					//抛出异常
		}
		int nRet = nDiv / nDivisor;						//进行触发运算
		cout << nRet << endl;
	}
	catch(...)										//异常捕捉
	{
		cout << "运算失败!" << endl;
	}
	return 0;
}

4、自定义异常类

        下面代码定义了两个异常,一个除0的异常类,一个负数异常类。

#include "stdafx.h"
#include "iostream.h"
#include "string.h"

class CDivZeroException						//定义一个除零的异常类
{
public:
	char ExceptionMsg[128];					//定义数据成员
	CDivZeroException()						//定义构造函数
	{
		strcpy(ExceptionMsg,"除零错误");		//设置异常信息
	}
};
class CNegException 						//定义一个负数异常类
{
public:
	char ExceptionMsg[128];					//定义数据成员
	CNegException()						//定义构造函数
	{
		strcpy(ExceptionMsg,"除数为负数错误");	//设置异常信息
	}
};

bool Div(int nDiv ,int nDivisor, int &nRet)			//定义除法函数
{
	try									//异常捕捉
	{
		if (nDivisor == 0)					//判断除数是否为0
			throw CDivZeroException();		//抛出异常
		else if ( nDivisor < 0)					//判断除数是否为负数
			throw CNegException();			//抛出异常
		else
			nRet = nDiv / nDivisor;			//进行除法运算
	}
	catch(CDivZeroException e)				//捕捉除零的异常
	{
		cout << e.ExceptionMsg << endl;		//输出异常信息
		return false;
	}
	catch(CNegException e)					//捕捉除数为负数的异常
	{
		cout << e.ExceptionMsg << endl;		//输出异常信息
		return false;
	}
	return true;
}

int main(int argc, char* argv[])
{
	int nRet;								//定义一个变量
	bool bRet = Div(100, -2, nRet);				//调用Div函数
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坐望云起

如果觉得有用,请不吝打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值