异常类型和异常变量的生命周期

C++异常处理机制详解
本文深入探讨了C++中的异常处理机制,包括throw不同类型的异常(如int、字符串、类对象),并通过具体案例展示了如何使用try-catch块来捕获和处理这些异常。此外,文章还介绍了异常层次结构的概念,以及如何利用C++标准库中的异常类型来增强程序的健壮性和可维护性。

1)throw的异常是有类型的,可以使,数字、字符串、类对象。

2)throw的异常是有类型的,catch严格按照类型进行匹配。

3)注意 异常对象的内存模型  。

 

一、 传统处理错误

//文件的二进制copy
int filecopy01(char *filename2, char *filename1 )
{
	FILE *fp1= NULL,  *fp2 = NULL;

	fp1 = fopen(filename1, "rb");
	if (fp1 == NULL)
	{
		return 1;
	}

	fp2 = fopen(filename2, "wb");
	if (fp1 == NULL)
	{
		return 2;
	}

	char buf[256];
	int  readlen, writelen;
	while ( (readlen = fread(buf, 1, 256, fp1)) > 0 ) //如果读到数据,则大于0 
	{
		writelen = fwrite(buf, 1, readlen, fp2);
		if (readlen != readlen)
		{
			return 3;
		}
	}

	fclose(fp1);
	fclose(fp2);
	return 0;
}
测试程序
void main()
{
	int ret;
	ret = filecopy01("c:/1.txt","c:/2.txt");
	if (ret !=0 )
	{
		switch(ret)
		{
		case 1:
			printf("打开源文件时出错!\n");
			break;
		case 2:
			printf("打开目标文件时出错!\n");
			break;
		case 3:
			printf("拷贝文件时出错!\n");
			break;
		default:
			printf("发生未知错误!\n");
			break;
		}
	}
}

 

 

二、throw int类型异常

/文件的二进制copy
void filecopy02(char *filename2, char *filename1 )
{
	FILE *fp1= NULL,  *fp2 = NULL;

	fp1 = fopen(filename1, "rb");
	if (fp1 == NULL)
	{
		//return 1;
		throw 1;
	}

	fp2 = fopen(filename2, "wb");
	if (fp1 == NULL)
	{
		//return 2;
		throw 2;
	}

	char buf[256];
	int  readlen, writelen;
	while ( (readlen = fread(buf, 1, 256, fp1)) > 0 ) //如果读到数据,则大于0 
	{
		writelen = fwrite(buf, 1, readlen, fp2);
		if (readlen != readlen)
		{
			//return 3;
			throw 3;
		}
	}

	fclose(fp1);
	fclose(fp2);
	return ;
}

  

三、throw字符类型异常

//文件的二进制copy
void filecopy03(char *filename2, char *filename1 )
{
	FILE *fp1= NULL,  *fp2 = NULL;

	fp1 = fopen(filename1, "rb");
	if (fp1 == NULL)
	{
		throw "打开源文件时出错";
	}

	fp2 = fopen(filename2, "wb");
	if (fp1 == NULL)
	{
		throw "打开目标文件时出错";
	}

	char buf[256];
	int  readlen, writelen;
	while ( (readlen = fread(buf, 1, 256, fp1)) > 0 ) //如果读到数据,则大于0 
	{
		writelen = fwrite(buf, 1, readlen, fp2);
		if (readlen != readlen)
		{
			throw "拷贝文件过程中失败";
		}
	}

	fclose(fp1);
	fclose(fp2);
	return ;
}

  

四、throw类对象类型异常

//throw int类型变量
//throw 字符串类型
//throw 类类型
class BadSrcFile 
{
public:
	BadSrcFile()
	{
		cout << "BadSrcFile 构造 do "<<endl;
	}
	~BadSrcFile()
	{
		cout << "BadSrcFile 析构 do "<<endl;
	}
	BadSrcFile(BadSrcFile & obj)
	{
		cout << "拷贝构造  do "<<endl;
	}
	void toString()
	{
		cout << "aaaa" << endl;
	}

};
class BadDestFile {};
class BadCpyFile {};;

void filecopy04(char *filename2, char *filename1 )
{
	FILE *fp1= NULL,  *fp2 = NULL;

	fp1 = fopen(filename1, "rb");
	if (fp1 == NULL)
	{
		//throw new BadSrcFile();
		throw  BadSrcFile();
	}

	fp2 = fopen(filename2, "wb");
	if (fp1 == NULL)
	{
		throw BadDestFile();
	}

	char buf[256];
	int  readlen, writelen;
	while ( (readlen = fread(buf, 1, 256, fp1)) > 0 ) //如果读到数据,则大于0 
	{
		writelen = fwrite(buf, 1, readlen, fp2);
		if (readlen != readlen)
		{
			throw BadCpyFile();
		}
	}

	fclose(fp1);
	fclose(fp2);
	return ;
}

main测试案例 //结论://C++编译器通过throw 来产生对象,C++编译器再执行对应的catch分支,相当于一个函数调用,把实参传递给形参。 void main() { try { //filecopy02("c:/1.txt","c:/2.txt"); // filecopy03("c:/1.txt","c:/2.txt"); filecopy04("c:/1.txt","c:/2.txt"); } catch (int e) { printf("发生异常:%d \n", e); } catch (const char * e) { printf("发生异常:%s \n", e); } catch ( BadSrcFile *e) { e->toString(); printf("发生异常:打开源文件时出错!\n"); } catch ( BadSrcFile &e) { e.toString(); printf("发生异常:打开源文件时出错!\n"); } catch ( BadDestFile e) { printf("发生异常:打开目标文件时出错!\n"); } catch ( BadCpyFile e) { printf("发生异常:copy时出错!\n"); } catch(...) //抓漏网之鱼 { printf("发生了未知异常! 抓漏网之鱼\n"); } //class BadSrcFile {}; //class BadDestFile {}; //class BadCpyFile {};; }

  

异常的层次结构(继承在异常中的应用)

1.异常是类 – 创建自己的异常类

2.异常派生

3.异常中的数据:数据成员

4.按引用传递异常

  -->在异常中使用虚函数

 

五、标准程序库异常

 

 

案例1:

#include "iostream"
using namespace std;
#include <stdexcept>  
 
class Teacher
{
public:
	Teacher(int age)  //构造函数, 通过异常机制 处理错误
	{
		if (age > 100)
		{
			throw out_of_range("年龄太大");
		}
		this->age = age;
	}
protected:
private:
	int age;
};

void mainxx()
{
	try
	{
		Teacher t1(102);
	}
	catch (out_of_range e)
	{
		
		cout << e.what() << endl;
	}

	exception e;
	system("pause");
}

  

 

案例2

class Dog
{
public:
	Dog()
	{
		parr = new int[1024*1024*100]; //4MB
	}
private:
	int *parr;
};

int main31()
{
	Dog *pDog;
	try{
		for(int i=1; i<1024; i++) //40GB!
		{
			pDog = new Dog();
			cout << i << ": new Dog 成功." << endl;
		}
	}
	catch(bad_alloc err)
	{
		cout << "new Dog 失败: " << err.what() << endl;
	}

	return 0;

}

  

案例3

 

转载于:https://www.cnblogs.com/gd-luojialin/p/9750352.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值