⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ex21.cpp

📁 C/C++程序设计教程
💻 CPP
字号:
  
          //  第21章   异常处理技术


   // [例21.1] C++异常处理技术
	# include <stdio.h>
	long DivThrow(long x,long y)
	{	if(y==0) throw x;
		return x/y;
	}
	void ExceptHanding(long u,long v)
	{	try
		{	 long	d=DivThrow(u,v);
		     printf("ExceptHanding %d/%d=%d\n",u,v,d);
		}	
		catch(long x)
		{ printf("ExceptHanding=%d. Can't divided by zero\n",x);		}
	}
	void main()
	{	ExceptHanding(5,3);       //输出结果ExceptHanding 5/3=1
	    ExceptHanding(5,0);       //输出结果ExceptHanding=5. Can't divided by zero
	}
    //[例21.2]if语句加静态变量的跟踪
	# include <stdio.h>
	enum {NoZero=1,IsZero=1000};
	static int sTrace=NoZero;
	long DivideIf(long x,long y)
	{	if(y==0){ sTrace=IsZero; return x;  }
		return x/y;
	}
	void TraceHanding(long u,long v)
	{	long d=DivideIf(u,v);
		switch(sTrace)
		{	case NoZero: printf("TraceHanding %d/%d=%d\n",u,v,d);break;
			case IsZero:  printf("TraceHanding %d. Can't divided by zero\n",d);break;
		}
	}
	void main()
	{	 TraceHanding(6,2);          //输出结果TraceHanding 6/2=3
	    TraceHanding(2,0);          //输出结果TraceHanding 2. Can't divided by zero
	}

//[例21.3] 异常的多路捕获
	# include <stdio.h>
	enum enumType {eChars,eLong,eClass,eUnknown,eSkip};
	class ClassE{};
	struct Unknown{};
	void PolyHanding(int kind)
	{   if(kind==eSkip) throw eSkip;               //这个throw语句匹配外层的try块
		try
		{ if(kind==eChars)   throw "string type";      //
	     if(kind==eLong)    throw (long)kind;
		 if(kind==eClass)     throw ClassE();           //throw显式调用构造函数
		 if(kind==eUnknown) throw Unknown();          //调用缺省构造函数Unknown()  
		}		
	    catch(char* s)		{ printf("Except Handler is=%s\t",s);}
  	    catch(long)		{ printf("Except Handler is long type\t");}
	    catch(ClassE)		{ printf("Except Handler is ClassE type\t");}
	    catch(...)			{ printf("Except Handler is Unknown type\t");	}
		printf("Embeded try~catch block is not skip\n");
	}
	void main()
	{	try 
		{	PolyHanding(eChars);               //程序内部的异常在内部有效处理
			PolyHanding(eLong);                //流程依次执行函数调用
			PolyHanding(eClass);
			PolyHanding(eUnknown);           //程序内部的异常在内部有效处理
			PolyHanding(eSkip);	            //函数调用引发外层try块的throw语句
			PolyHanding(eLong);               //这两个函数调用是程序的死码区 
			PolyHanding(eClass);
		}
		catch(enumType)                        //拦截梅举类enumType的异常流
		{   printf("Embeded try~catch block is  skipped\n");	}	 
		printf("this printf  is a must  route\n");     //这个printf语句是流程的必由之路
	}              //输出如下:

//[例21.4] 异常的重新抛出
   # include <stdio.h>
    enum  {eLong,eUnknown,eSpecial};
	struct Unknown{};
    class Special{};
	void fa(int kind)
	{   try {
          if(kind==eSpecial) 	    throw Special();
		  if(kind==eUnknown)     throw Unknown();
		}		
	    catch(Special)	{ printf("fa Rethrowing Special Exception out\n");
		  throw;    //相当于 throw Special()到上层fb的 catch(Special)入口
		}
	    catch(...)	   { printf("fa Rethrowing Unknown Exception out\n");
		  throw;     //相当于throw Unknown()到上层fb的catch(...)
		}	
	    printf("normal process in fa\t");	
	}
	void fb(int kind)
	{  try	{ fa(kind);}
	   catch(Special)
		{ printf("fb Rethrowing Special Exception out\n");
		  throw; //相当于 throw Special()到上层fc的 catch(Special)入口
		}
	    catch(...)	{  printf("Unknown Exception  treated here in fb\n");}
	    printf("normal process in fb\n"); 
	}
	void fc(int kind)
	{ 	try
		{  fb(kind);	
		 if(kind==eLong)    throw (long)kind; 
		}
		catch(long)		{ printf("long type Exception is in fc \n");}	   
	    catch(Special)		{ printf("Special Exception  is treated here in fc \n");}
	}
	void main()	{	fc(eLong);		fc(eUnknown);		fc(eSpecial);	}
//[例21.5]异常过程中对象的清除
     #include<stdio.h>
	class ClassB 
	{	public:	int m_b;
		ClassB(int n=1) {m_b=n;printf("%d.ClassB::ClassB(),this=%p\n",m_b,this);}
	    ~ClassB()     {       printf("%d.ClassB::~ClassB()\n",m_b);}		
	};
	class ClassC 
	{    public:	int m_c;  
		ClassC(int n=2) 	{m_c=n;printf("%d.ClassC::ClassC(),this=%p\n",m_c,this);}
		~ClassC()      {   printf("%d.ClassC::~ClassC()\n",m_c);   }
		void Show()     {   printf("Show m_c=%d,this=%p \n",m_c,this); }
	};
	enum {eObjc=888,eObjh=3};
	void fa(int k)
	{	if(k==eObjc) {
			printf("send local Objc with k=%d\n",eObjc);
			throw ClassC(k);	                       //直接抛出一个无名对象
		}
		ClassB objb(2);                              //中间定义一个局部对象objb2
		ClassC *pObjc=new ClassC(k);                //定义一个Heap空间的对象
		printf("send Heap obj with k=%d\n",k);
		   throw pObjc;                              //无过滤条件的抛出对象指针
		printf("this code area is dead block\n");             //死码区
		delete pObjc;	
	}
	void fb(int k)
	{	printf("Enter regular routine with k=%d\n",k);
		try{ 	ClassB objb(1);                           //定义局部变量objb1
		    fa(k);
		}
	    catch(ClassC objc )                            //接受数值对象的入口处理器
		{   printf("local Objc received\n");
		    objc.Show();	
		}
		catch(ClassC *p=NULL )                       //接受对象指针的入口处理器 
		{	if(p!=NULL)
			{   printf("Heap Obj received\n");
				p->Show();
				delete p;
			}		
		}	
	}
	void main()	{   fb(eObjc);          fb(eObjh);		}
//[例21.6]继承层次catch处理器的先后次序
    #include<stdio.h>
	class B  
	{	public: int m_b;
	    B (int n=1)    {m_b=n;printf("B::B()this=%p\n",this);}
			virtual ~B (){printf("B::~B()this=%p\n",this);}
			virtual int HandleError();			
	};
	class C : public B 
	{ public:	int m_c;  
		C()    {m_c=2;printf("C::C()this=%p\n",this);}
		virtual ~C(){printf("C::~C()this=%p\n",this);}		
		virtual int HandleError();	 
	};
	class D : public C
	{   public:	int m_d;  
		D(){m_d=4; printf("D::D()this=%p\n",this);}  			
		virtual ~D(){printf("D::~D()this=%p\n",this);}
		virtual int HandleError();  
	};
    int B::HandleError()	{printf("B::HandleError()this=%p\n",this);return 1;}
	int C::HandleError()	{printf("C::HandleError()this=%p\n",this);return 0;}
	int D::HandleError()	{printf("D::HandleError()this=%p\n",this);return 1;}
	enum{classb,classc,classd,etype1,etype2};
	int   ErrorInfo(int k) //对错误消息进行分流的函数
	{ switch(k)
	  {	case etype1: return etype1;
		case etype2: return etype2;
	    default :    return etype2+1;
	  }    
	}
	void ThrowHandler(int k)
	{   switch(k)                               //throw的表达式先完成副作用
		{ case classb: throw B();                   //抛出基类的无名对象
		  case classc: throw C();                   //抛出直接派生类对象
		  case classd: throw D();                   //抛出间接派生类对象
          default :    throw ErrorInfo(k);           //抛出其它错误消息
	    }	                                   
	}
	void VirtualHandling(int k)
	{	try  {ThrowHandler(k); }                  //抛出两种类型的异常
		catch(B & rBase) {                         //基对象的引用形参
			rBase.HandleError();		              //对象别名虚拟调用虚函数
		}	
		catch(int k)                                  //捕获整型数值类型消息
		{  switch(k)                                 //消息根据具体的数值分流
			{ case etype1: printf("etype1 Error treated here\n");break;
			  case etype2: printf("etype2 Error treated here\n");break;
			  default:    printf("a type Error treated here\n");break;
			}
		}	
	}
	void DerivedFirst(int k)                    
	{    try      {ThrowHandler(k);}
		//catch(B  b){b.HandleError();}	 //警告'class D' : is caught by base class ('class B ')
		catch(D d)  {d.HandleError();}	 //间接派生类对象数值形参catch块置于前面
		catch(C c)  {c.HandleError();}	//直接派生类对象数值形参catch块置于中间
		catch(B b)  {b.HandleError();}	//基类对象数值形参catch块置于最后
        catch(int ) { printf("a int  Error treated here\n");	}	
	}
	 void main()
	 {  ////VirtualHandling(etype2+7);输出结果a type Error treated here
	    VirtualHandling(classd); 	            DerivedFirst(classc);	
	 }



318



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -