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


    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("打开源文件时出错!
    ");
    			break;
    		case 2:
    			printf("打开目标文件时出错!
    ");
    			break;
    		case 3:
    			printf("拷贝文件时出错!
    ");
    			break;
    		default:
    			printf("发生未知错误!
    ");
    			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 ", e); } catch (const char * e) { printf("发生异常:%s ", e); } catch ( BadSrcFile *e) { e->toString(); printf("发生异常:打开源文件时出错! "); } catch ( BadSrcFile &e) { e.toString(); printf("发生异常:打开源文件时出错! "); } catch ( BadDestFile e) { printf("发生异常:打开目标文件时出错! "); } catch ( BadCpyFile e) { printf("发生异常:copy时出错! "); } catch(...) //抓漏网之鱼 { printf("发生了未知异常! 抓漏网之鱼 "); } //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

  • 相关阅读:
    SGU 275. To xor or not to xor
    4364: [IOI2014]wall砖墙
    3211: 花神游历各国
    5248: [2018多省省队联测]一双木棋
    3106: [cqoi2013]棋盘游戏
    POJ 1568 Find the Winning Move
    P3527 [POI2011]MET-Meteors
    P2617 Dynamic Rankings
    3262: 陌上花开
    1176: [Balkan2007]Mokia
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/9750352.html
Copyright © 2020-2023  润新知