上一节已经实现了异常基类的功能,接下来将实现基于该基类的几个父类
功能定义如下
异常类 |
功能描述 |
ArithmeticException |
计算异常 |
NullPointerException |
空指针异常 |
IndexOutOfBoundsException |
越界异常 |
NotEnoughMemoryException |
内存不足异常 |
InvalidParameterException |
参数错误异常 |
为了代码简洁,定义一个宏
#define THROW_EXCEPTION(e, m) (throw e(m, __FILE__, __LINE__))//e为异常类类型
如果这个宏看不懂,就想一下throw函数的使用(可参见上一节)
要做的很简单,就是继承这个基类
完整代码如下
Exception.h
1 #ifndef _EXCEPTION_H_ 2 #define _EXCEPTION_H_ 3 4 5 6 namespace DataStructureLib 7 { 8 #define THROW_EXCEPTION(e,m) throw e(m,__FILE__,__LINE__) 9 class Exception 10 { 11 protected: 12 char* m_message; 13 char* m_location; 14 protected: 15 void init(const char*,const char*,int);//由于三个构造函数中的逻辑很相似,所以可以将相似的部分统一放到一个函数init() 16 public: 17 Exception(const char* message); 18 Exception(const char* file,int line); 19 Exception(const char* message,const char* file,int line); 20 21 //涉及到堆空间即需进行深拷贝,拷贝构造函数和"=" 22 Exception(const Exception& e); 23 Exception& operator =(const Exception& e); 24 25 virtual const char* message() const; 26 virtual const char* location() const; 27 28 virtual ~Exception(void)= 0; 29 }; 30 //计算异常类 31 class ArithmeticException: public Exception 32 { 33 public: 34 ArithmeticException():Exception(0){} 35 ArithmeticException(const char* message):Exception(message){} 36 ArithmeticException(const char*file, int line):Exception(file, line){} 37 ArithmeticException(const char *message, const char* file, int line):Exception(message, file, line){} 38 39 ArithmeticException(const ArithmeticException& e): Exception(e){} 40 ArithmeticException& operator=(const ArithmeticException& e) 41 { 42 Exception::operator =(e); 43 44 return *this; 45 } 46 }; 47 48 49 50 51 //空指针异常 52 class NullPointerException: public Exception 53 { 54 public: 55 NullPointerException():Exception(0){} 56 NullPointerException(const char* message):Exception(message){} 57 NullPointerException(const char*file, int line):Exception(file, line){} 58 NullPointerException(const char *message, const char* file, int line):Exception(message, file, line){} 59 60 NullPointerException(const NullPointerException& e): Exception(e){} 61 NullPointerException& operator=(const NullPointerException& e) 62 { 63 Exception::operator =(e); 64 65 return *this; 66 } 67 }; 68 69 //越界异常类 70 class IndexOutOfBoundsException: public Exception 71 { 72 public: 73 IndexOutOfBoundsException():Exception(0){} 74 IndexOutOfBoundsException(const char* message):Exception(message){} 75 IndexOutOfBoundsException(const char*file, int line):Exception(file, line){} 76 IndexOutOfBoundsException(const char *message, const char* file, int line):Exception(message, file, line){} 77 78 IndexOutOfBoundsException(const IndexOutOfBoundsException& e): Exception(e){} 79 IndexOutOfBoundsException& operator=(const IndexOutOfBoundsException& e) 80 { 81 Exception::operator =(e); 82 83 return *this; 84 } 85 }; 86 87 //内存不足异常类 88 class NotEnoughMemoryException: public Exception 89 { 90 public: 91 NotEnoughMemoryException():Exception(0){} 92 NotEnoughMemoryException(const char* message):Exception(message){} 93 NotEnoughMemoryException(const char*file, int line):Exception(file, line){} 94 NotEnoughMemoryException(const char *message, const char* file, int line):Exception(message, file, line){} 95 96 NotEnoughMemoryException(const NotEnoughMemoryException& e): Exception(e){} 97 NotEnoughMemoryException& operator=(const NotEnoughMemoryException& e) 98 { 99 Exception::operator =(e); 100 101 return *this; 102 } 103 }; 104 105 //参数错误异常类 106 class InvalidParameterException: public Exception 107 { 108 public: 109 InvalidParameterException():Exception(0){} 110 InvalidParameterException(const char* message):Exception(message){} 111 InvalidParameterException(const char*file, int line):Exception(file, line){} 112 InvalidParameterException(const char *message, const char* file, int line):Exception(message, file, line){} 113 114 InvalidParameterException(const InvalidParameterException& e): Exception(e){} 115 InvalidParameterException& operator=(const InvalidParameterException& e) 116 { 117 Exception::operator =(e); 118 119 return *this; 120 } 121 }; 122 123 #endif 124 }
Exception.cpp
1 #include "Exception.h" 2 #include <cstring> 3 #include <cstdlib> 4 5 namespace DataStructureLib 6 { 7 void Exception::init(const char* message,const char* file,int line) 8 { 9 m_message=strdup(message);//这里不能直接使用m_message=message, 10 //因为message指针指向的数据有可能会在栈、堆、全局区,如果是在栈上,局部变量可能会消失,如果直接使用m_message=message就会不安全 11 if(file!=NULL) 12 { 13 char sl[16]={0}; 14 itoa(line,sl,10);//将line转为char类型 10代表十进制 15 16 m_location=static_cast<char* >(malloc(strlen(file)+strlen(sl)+2));//加2表示后面的":"和结束符即“/0” 17 m_location=strcpy(m_location,file); 18 m_location=strcat(m_location,":"); 19 m_location=strcat(m_location,sl); 20 } 21 } 22 23 Exception:: Exception(const char* message) 24 { 25 init(message,NULL,0); 26 } 27 28 Exception::Exception(const char* file,int line) 29 { 30 init(NULL,file,line); 31 } 32 33 Exception::Exception(const char* message,const char* file,int line) 34 { 35 init(message,file,line); 36 } 37 38 Exception::~Exception(void) 39 { 40 41 free(m_message); 42 free(m_location); 43 } 44 45 const char* Exception::message() const 46 { 47 return m_message; 48 } 49 50 const char* Exception::location() const 51 { 52 return m_location; 53 } 54 55 Exception::Exception(const Exception& e) 56 { 57 m_message=strdup(e.m_message); 58 m_location=strdup(e.m_location); 59 } 60 61 Exception& Exception::operator =(const Exception& e) 62 { 63 if (this!=&e) 64 { 65 free(m_message); 66 free(m_location); 67 68 m_message=strdup(e.m_message); 69 m_location=strdup(e.m_location); 70 } 71 return *this; 72 } 73 74 }
测试
1 #include <iostream> 2 #include "Exception.h" 3 4 using namespace std; 5 using namespace DataStructureLib; 6 7 int main() 8 { 9 try{ 10 THROW_EXCEPTION(NullPointerException,"test"); 11 } 12 13 catch(const ArithmeticException& e) 14 { 15 cout<<"ArithmeticException "<<endl; 16 cout<<e.location()<<endl; 17 cout<<e.message()<<endl; 18 } 19 catch(const NullPointerException& e) 20 { 21 cout<<"NullPointerException"<<endl; 22 cout<<e.location()<<endl; 23 cout<<e.message()<<endl; 24 } 25 26 catch(const Exception& e) 27 { 28 cout<<"Exception"<<endl; 29 cout<<e.location()<<endl; 30 cout<<e.message()<<endl; 31 } 32 33 system("pause"); 34 return 0; 35 }