异常类之派生类

时间:2022-09-08 09:09:25

上一节已经实现了异常基类的功能,接下来将实现基于该基类的几个父类

功能定义如下

异常类

功能描述

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 }
View Code

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 }
View Code

测试

异常类之派生类异常类之派生类
 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 }
View Code