C++ 中的异常处理catch 语句块中可以抛出异常编程实验: catch 中抛出异常#include <iostream>using namespace std;int main(){ try { try { throw ‘c’; } catch(int i) { cout << “Inner: catch(int i)” << endl; throw i; } catch(…) { cout << “Inner: catch(…)” << endl; throw; } } catch(…) { cout << “Outer: catch(…)” << endl; } return 0;}输出:Inner: catch(…)Outer: catch(…)问题:为什么要在 catch 中重新抛出异常?catch 中捕获得异常可以被重新解释后抛出工程开发中使用这样得方式统一异常类型编程实验: 异常的重新解释#include <iostream>using namespace std;/* 假设: 当前的函数是第三方库中的函数,因此,我们无法修改源代码 函数名: void func(int i) 抛出异常的类型: int -1 ==》 参数异常 -2 ==》 运行异常 -3 ==》 超时异常*/void func(int i){ if( i < 0 ) { throw -1; } if( i > 100 ) { throw -2; } if( i == 11 ) { throw -3; } cout << “Run func… " << endl;}void MyFunc(int i){ try { func(i); } catch(int i) { switch(i) { case -1: throw “Invalid Parameter”; break; case -2: throw “Runtime Exception”; break; case -3: throw “Timeout Exception”; break; } }}int main(){ try { MyFunc(11); } catch(const char* cs) { cout << “Exception Info: " << cs << endl; } return 0;}输出:Exception Info: Timeout Exception异常的类型可以是自定义类型对于类类型异常的匹配依旧是至上而下严格匹配赋值兼容性原则在异常匹配中依然适用一般而言匹配子类异常的 catch 放在上部匹配父类异常的 catch 放在下部工程中会定义一系列的异常类每个类代表工程中可能出现的一种异常类型代码复用时可能需要重解释不同的异常类在定义 catch 语句块时推荐使用引用作为参数(避开拷贝构造,提高程序效率)编程实验: 类类型的异常#include <iostream>#include <string>using namespace std;class Base{};class Exception : public Base{private: int m_id; string m_desc;public: Exception(int id, string desc) { m_id = id; m_desc = desc; } int id() const { return m_id; } string description() const { return m_desc; }};/* 假设: 当前的函数是第三方库中的函数,因此,我们无法修改源代码 函数名: void func(int i) 抛出异常的类型: int -1 ==》 参数异常 -2 ==》 运行一场 -3 ==》 超时异常*/void func(int i){ if( i < 0 ) { throw -1; } if( i > 100 ) { throw -2; } if( i == 11 ) { throw -3; } cout << “Run func… " << endl;}void MyFunc(int i){ try { func(i); } catch(int i) { switch(i) { case -1: throw Exception(-1, “Invalid Parameter”); break; case -2: throw Exception(-2, “Runtime Exception”); break; case -3: throw Exception(-3, “Timeout Exception”); break; } }}int main(){ try { MyFunc(11); } catch(const Exception& e) { cout << “Exception Info: " << endl; cout << " ID: " << e.id() << endl; cout << " Description: " << e.description() << endl; } return 0;}输出:Exception Info: ID: -3 Description: Timeout Exception C++ 标准库中提供了实用异常类标准库中的异常都是从 exception 类派生的exception 类主要有两个主要的分支logic_error常用于程序中的可避免逻辑错误runtime_error常用于程序中无法避免的恶性错误标准库中的异常编程实验: 标准库中的异常使用Array.h#ifndef ARRAY_H#define ARRAY_H#include <stdexcept>using namespace std;template< typename T, int N >class Array{private: T m_array[N];public: int length() const; bool set(int index, T value); bool get(int index, T& value); T& operator[] (int index); T operator[] (int index) const; virtual ~Array();};template< typename T, int N >int Array<T, N>::length() const{ return N;}template< typename T, int N >bool Array<T, N>::set(int index, T value){ bool ret = (index >=0) && (index < N); if( ret ) { m_array[index] = value; } return ret;}template< typename T, int N >bool Array<T, N>::get(int index, T& value){ bool ret = (index >=0) && (index < N); if( ret ) { value = m_array[index]; } return ret;}template< typename T, int N >T& Array<T, N>::operator[] (int index){ if( (index >=0) && (index < N) ) { return m_array[index]; } else { throw out_of_range(“T& Array<T, N>::operator[] (int index)”); }}template< typename T, int N >T Array<T, N>::operator[] (int index) const{ if( (index >=0) && (index < N) ) { return m_array[index]; } else { throw out_of_range(“T Array<T, N>::operator[] (int index)”); } }template< typename T, int N >Array<T, N>::~Array(){}#endifHeapArray.h#ifndef HEAPRRAY_H#define HEAPARRAY_H#include <stdexcept>using namespace std;template< typename T >class HeapArray{private: int m_length; T* m_pointer; HeapArray(int len); HeapArray(const HeapArray& obj); bool construct();public: static HeapArray* NewInstance(int length); int length() const; bool get(int index, T& value); bool set(int index, T value); T& operator [] (int index); T operator [] (int index) const; HeapArray& operator = (const HeapArray& obj); HeapArray& self(); const HeapArray& self() const; ~HeapArray();};template< typename T >HeapArray<T>::HeapArray(int len){ m_length = len;}template< typename T >bool HeapArray<T>::construct(){ m_pointer = new T[m_length]; return m_pointer != NULL;}template< typename T >HeapArray<T>* HeapArray<T>::NewInstance(int length){ HeapArray<T>* ret = new HeapArray(length); if( !(ret && (ret->construct())) ) { delete ret; ret = 0; } return ret;}template< typename T >int HeapArray<T>::length() const{ return m_length;}template< typename T >bool HeapArray<T>::get(int index, T& value){ bool ret = (index >= 0) && (index < length()); if( ret ) { value = m_pointer[index]; } return ret;}template< typename T >bool HeapArray<T>::set(int index, T value){ bool ret = (index >= 0) && (index < length()); if( ret ) { m_pointer[index] = value; } return ret;}template< typename T >T& HeapArray<T>:: operator [] (int index){ if( (index >= 0) && (index < length()) ) { return m_pointer[index]; } else { throw out_of_range(“T& HeapArray<T>::operator[] (int index)”); }}template< typename T >T HeapArray<T>:: operator [] (int index) const{ if( (index >= 0) && (index < length()) ) { return m_pointer[index]; } else { throw out_of_range(“T HeapArray<T>::operator[] (int index)”); }}template< typename T >HeapArray<T>& HeapArray<T>:: operator = (const HeapArray<T>& obj){ if( this != &obj ) { T* pointer = new T[obj.m_length]; if( pointer ) { for(int i=0; i<obj.m_length; i++) { pointer[i] = obj.m_pointer[i]; } m_length = obj.m_length; delete m_pointer; m_pointer = pointer; } } return *this;}template< typename T >HeapArray<T>& HeapArray<T>::self(){ return *this;}template< typename T >const HeapArray<T>& HeapArray<T>::self() const{ return this;}template< typename T >HeapArray<T>::~HeapArray(){ delete[] m_pointer;}#endifmain.cpp#include <iostream>#include “Array.h”#include “HeapArray.h"using namespace std;void TestArray(){ Array<int, 5> a; for(int i=0; i<a.length(); i++) { a[i] = i; } for(int i=0; i<a.length(); i++) { cout << a[i] << endl; }}void TestHeapArray(){ HeapArray<double> pa = HeapArray<double>::NewInstance(5); if( pa != NULL ) { HeapArray<double>& array = pa->self(); for(int i=0; i<array.length(); i++) { array[i] = i; } for(int i=0; i<array.length(); i++) { cout << array[i] << endl; } } delete pa;}int main(){ try { TestArray(); cout << endl; TestHeapArray(); } catch(…) { cout << “Exception” << endl; } return 0;}输出:0123401234小结catch 语句块中可以抛出异常异常的类型可以是自定义类类型赋值兼容性在异常匹配中依然适用标准库中的异常都是从 exception 类派生的以上内容参考狄泰软件学院系列课程,请大家保护原创