欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

异常处理

程序员文章站 2022-07-06 12:34:38
异常处理 1.异常基本概念与用法 方法内throw throw啥类型,catch就需要指定成啥类型,否则,就catch不到, 但是如果有catch(…),当它上面的catch都没有catch到,就会被catch(…) catch到。而且catch(…)必须放到最后。 c++ include usin ......

异常处理

1.异常基本概念与用法

  • 方法内throw

throw啥类型,catch就需要指定成啥类型,否则,就catch不到, 但是如果有catch(…),当它上面的catch都没有catch到,就会被catch(…) catch到。而且catch(…)必须放到最后。

#include <iostream>
using namespace std;

float divs(const int& a, const int& b){
  if(b == 0){
    short x;
    throw x;
  }
  return a/b;
}

int main(){
  int a = 10;
  int b = 0;
  try{
    float r = divs(a,b);
    cout << r << endl;
  }
  catch(int){
    cout << "Div err(int)" << endl;
  }
  catch(short){
    cout << "Div err(short)" << endl;
  }
  catch(...){//必须放到最后       
  }
}
  • 方法声明出throw

只能够抛出声明出的类型,下面的例子就只能抛出short,int类型的异常,别的类型的异常是不能抛出去的。

下面的例子,编译没有问题,但是运行就会崩溃,因为方法内抛出的long类型的异常,但是方法声明的地方,不允许抛出long类型的异常。

#include <iostream>
using namespace std;

float divs(const int& a, const int& b)throw(short, int){
  if(b == 0){
    long x;
    throw x;
  }
  return a/b;
}

int main(){
  int a = 10;
  int b = 0;
  try{
    float r = divs(a,b);
    cout << r << endl;
  }
  catch(int){
    cout << "Div err(int)" << endl;
  }
  catch(short){
    cout << "Div err(short)" << endl;
  }
  catch(...){//必须放到最后       
  }
}
  • 方法不允许抛出异常

方法声明时,用throw()的话,就表明这个方法不允许抛出任何异常。

下面的例子,编译可以通过,运行崩溃。

#include <iostream>
using namespace std;

float divs(const int& a, const int& b)throw(){
  if(b == 0){
    short x;
    throw x;
  }
  return a/b;
}

int main(){
  int a = 10;
  int b = 0;
  try{
    float r = divs(a,b);
    cout << r << endl;
  }
  catch(int){
    cout << "Div err(int)" << endl;
  }
  catch(short){
    cout << "Div err(short)" << endl;
  }
  catch(...){//必须放到最后       
  }
}

2.自定义异常类

模拟栈的类,有push和pop接口,当push时,如果超过了最大空间就抛出异常;当pop时,如果达到栈的最底部就抛出异常,分别做了2个自定义异常类。

#include <iostream>
#include <string>

using namespace std;

template <typename Y>
class PushFull{
public:
  PushFull(const char* s, Y val) : str(s), value(val){
  }
  ~PushFull(){
  }
  void what(){
    cout << str << endl;
    cout << "value:" << value << endl;
  }
private:
  string str;
  Y value;
};

class PopEnd{
public:
  PopEnd(const char* s) : str(s){}
  ~PopEnd(){}
  void what(){
    cout << str << endl;
  }
private:
  string str;
};

template <typename T>
class Stack{
public:
  Stack(int sz = STACK_SIZE){
    cap = sz > STACK_SIZE ? sz :  STACK_SIZE;
    data = new T[cap];
    top = 0;
  }
  ~Stack(){
    delete []data;
    data = NULL;
    cap = top = 0;
  }
  bool isFull() const{
    return top >= cap;
  }
  bool push(const T& t){
    if(isFull()) {
      throw PushFull<T>("stack is full", t);
      return false;
    }
    data[top++] = t;
    return true;
  }
  bool isEnd(){
    return top <= 0;
  }
  T& pop(){
    if(isEnd()){
      throw PopEnd("stack is end");
      return data[0];
    }
    return data[--top];
  }
  void show(){
    for(int i = top - 1; i >= 0; --i){
      cout << data[i] << endl;
    }
  }
private:
  enum{STACK_SIZE = 8};
  T *data;
  size_t cap;
  size_t top;
};

int main(){
  Stack<int> s;
  try{
    for(int i = 1; i <= 8; ++i){
      s.push(i);
    }
  }
  catch(PushFull<int>& e){
    e.what();
  }
  //s.show();
  try{
    for(int i = 1; i <= 18; ++i){
      int p = s.pop();
      cout << p << endl; 
    }
  }
  catch(PopEnd& e){
    e.what();
  }
}