C++ How To Program整理(12)

@异常处理使得程序员能够将错误处理代码从程序执行的“主流程”中分离出来,提高程序的清晰度。
@在c++中,整数除法中如果除以0,程序将过早终止,在浮点数除法中,除数为0在一些版本的C++中是被允许的,它的结果是正或负的无穷大,输出为INF或-INF。
@runtime_error类,是标准库exception类的派生类,是C++描述运行时错误所创建的标准基类。
@exception是描述所有异常而创建的标准基类。
@一个从runtime_error派生而来的典型异常类只需要定义一个构造函数,这个构造函数将带有错误信息的字符串传递给基类runtime_error的构造函数
@几乎所有的异常类都从拥有一个virtual函数what的exception类派生而来,该函数返回异常项的错误信息。
  例子: 一个处理除数为0的异常的类
         #include<stdexcept>
         using namespace std;
        
         class DivideByZeroException:public runtime_error
         {
           public:
                DivideByZeroException():runtime_error("divid by zero")
                {}
         };
        
         验证代码:
         
          #include "DivideByZeroException.h"
          #include <iostream>
          using namespace std;
         
          double quotient(int numerator,int demoninator)
          {
            if(demoninator==0)
               throw DivideByZeroException();
              
               return static_cast<double> (numerator)/demoninator;        
          }
         
          int main()
          {
             int number1;
             int number2;
             double result;
            
             cout<<"Enter two integers(end of file to end)";
            
             while(cin>>number1>>number2)
             {
                try
                {
                  result= quotient(number1,number2);
                  cout<<"the quotient is:"<<result<<endl;
                }
               catch(DivideByZeroException &divideByZeroException)
               {
                 cout<<"Exception occurred:"<<divideByZeroException.what();       
               }           
            
             }
 
          }
         
@c++提供try语句块使之能够进行异常处理,一个try语句块由关键字try和后面跟着的一对花括号构成,花括号中定义了可能发生错误的语句块。
@异常是在catch中捕获和处理的,在每个try后应该立即跟着至少一个catch,catch后面跟着的圆括号包含异常参数,说明该catch所能处理的异常类型。
@当一个try块中异常发生时,那么将要执行的就是能够匹配这个异常的catch处理器。
@注意,一个catch处理器只有一个参数,多个参数是错误。
@不能在一个try语句后有两个catch处理器捕获相同的异常。
@如果异常发生在try语句块中,并且没有匹配的catch处理器,或者异常语句不再try语句块中,则拥有该语句的函数将立即终止,并且程序将尝试
定位调用函数中封装的try语句块,这个过程称为堆栈展开。
@异常处理是设计用来处理同步错误的,不处理异步事件,只写时间发生在语句正在执行的时候,常见的例子是:数组下标越界,运算溢出,除数为零,无效的函数参数和内存分配失败。         
@执行在catch处理器外的空throw语句将导致函数terminate被调用,程序放弃异常处理,并立即结束。
@catch处理器可以通过"throw;"重新抛出异常。
 重新抛出异常的例子:
            #include<iostream>
            #include<exception>
            using namespace std;
           
            void throwException()
            {
              try
              {
                 cout<<"before exception";
                 throw exception();
              }
              catch(exception &)
              {
                cout<<"exception happened";
                throw;
              }   
            }
           
            int main()
            {
              try
              {
                cout<<"before excute function";
                throwException();
              }
              catch(exception &)
                {
                  cout<<"exception handle again.";
                }      
            }
           
@异常规格,首先最好不要使用异常规格,除非重写一个已有异常规格的基类函数。
@异常规格声明如下:
          int someFunction(double value)
                  throw(ExceptionA, ExceptionB, ExceptionC)
                  {
                  }
  由上面可以看出,异常规格由紧接着函数参数列表的关键字throw开始,throw之后包含了能够抛出的异常类型
  如果函数抛出了这些类型之外的异常,那么异常处理机制将会调用unexpected来处理,throw()不含任何参数,表示不抛出异常,如果抛出,将调用unexception()
@堆栈展开,当异常被抛出但是没有在一个特定区域被捕获,该函数的调用堆栈将被展开,别试图在展开的外部try。。catch中捕获该异常。
  这要看下面的代码来理解更容易
                 #include<iostream>
                 #include<stdexcept>
                
                 using namespace std;
                
                 void function3()throw(runtime_error)
                 {
                   cout<<"in function3"<<endl;
                   throw runtime_error("runtime error in function3“);
                 }
               
                void function2()throw(runtime_error)
                 {
                   cout<<" function3 is called in func2"<<endl;
                   function3();
                 }    
                
                  void function1()throw(runtime_error)
                 {
                    cout<<" function2 is called in func2"<<endl;
                    function2();
                 }
                 
                 int main()
                 {
                   try
                   {
                    cout<<"function is called inside main"<<endl;
                    function1();
                   }
                   catch(runtime_error &error)
                   {
                     cout<<"Exception occurred:"<<error.what()<<endl;
                     cout<<"Exception handled in main"<<endl;                 
                   }
           }
 首先function1()被执行,调用function2,function2被执行调用function3,function3抛出异常,但是没有异常处理,所以堆栈展开,
 返回到function2,function2中也没有异常处理,所以继续展开到function1,function1中也没有,返回到main,main函数中有,所以catch被执行。
 @处理new失败
    1,C++标准指出,对于到new操作错误时,应当抛出bad_alloc异常(在头文件<new>中),下面是这种例子
              #include<iostream>
              #include<new>
             
              using namespace std;
             
              int main()
              {
                 double *ptr[50];
                
                 try
                 {
                    fot(int i=0;i<50;i++)
                    {
                      ptr[i]=new double[5000000];
                      cout<<"ptr["<<i<<"] ok";                
                    }
                 }
                 catch(bad_alloc &memoryException)
                 {
                  cout<<"Exception occurred"<<memoryException.what();             
                 }
              }          
  注意:(首先不推荐)在旧版本的C++中,new失败时将返回0,c++标准规定符合标准的编译器可以继续使用在失败时返回0的new版本,
  所以头文件<new>定义了nothrow对象(nothrow_t类型)用法如下
      double ×ptr=new(nothrow)double[78967895];
      上述语句使用了没有抛出bad_alloc的new版本分配内存。
    2,处理new失败的另一种方法是使用函数set_new_handler(在头文件<new>中)
     该函数的参数是一个没有参数没有返回值的函数指针。
     当new失败时,该函数被调用。这种犯法需要提前注册,如果没有注册new失败时候将会抛出bad_alloc异常。
    
     c++明确规定new处理器将要完成以下工作中的一个
        1,通过释放其他动态内存来增加可用内存,并返回运算符new来尝试再次分配内存。
        2,抛出bad_alloc异常
        3,调用函数abort或exit(在cstdlib中)
    下面是例子
      #include<iostream>
      #include<new>
      #include<cstdlib>
     
      void newHandler()
      {
        cout<<"called"<<endl;
        abort();
      }   
     
     
      int main()
      {
        double *ptr[50];
       
        set_new_handler(newHandler);
       
         fot(int i=0;i<50;i++)
            {
              ptr[i]=new double[5000000];
              cout<<"ptr["<<i<<"] ok";                
             }
      }
                         
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C++ How to Program (10th Edition) By 作者: Harvey M. Deitel Paul Deitel ISBN-10 书号: 9332585733 ISBN-13 书号: 9789332585737 Edition 版本: 10th 出版日期: 2017 Format: Paperback C++ How to Program presents leading-edge computing technologies in a friendly manner appropriate for introductory college course sequences, based on the curriculum recommendations of two key professional organizations–the ACM and the IEEE. The best-selling C++ How to Program is accessible to readers with little or no programming experience, yet comprehensive enough for the professional programmer. The Deitels’ signature live-code approach presents the concepts in the context of full working programs followed by sample executions. The early objects approach gets readers thinking about objects immediately–allowing them to more thoroughly master the concepts. Emphasis is placed on achieving program clarity and building well-engineered software. Interesting, entertaining, and challenging exercises encourage students to make a difference and use computers and the Internet to work on problems. To keep readers up-to-date with leading-edge computing technologies, the Tenth Edition conforms to the C++11 standard and the new C++14 standard. 1Introduction to Computers and C++ 2 Introduction to C++Programming,Input/Output and Operators 3Introduction to Classes,Objects,Member Functions and Strings 4Algorithm Development and Control Statements:Part 1 5 Control Statements:Part 2;Logical Operators 6Functions and an Introduction to Recursion 7 Class Templates array and vector;Catching Exceptions 8 Pointers 9 Classes:A Deeper Look 10 Operator Overloading;Class string 11 Object-Oriented Programming:Inheritance 12 Object-Oriented Programming:Polymorphism 13 Stream Input/Output:A Deeper Look 14File Processing 15 Standard Library Containers and lterators 16 Standard Library Algorithms 17 Exception Handling:A Deeper Look 18 Introduction to Custom Templates 19 Custom Templatized Data Structures 20 Searching and Sorting 21Cl

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值