zoukankan      html  css  js  c++  java
  • 创建数据结构库基础设施——异常类的构建

    1,数据结构库架构图(本文暂时架构图,后有更改):

     

    2,依赖异常类创建的库稳定性很好;

    3,异常类型可以是自定义类类型:

           1,对于类类型异常的匹配依旧是至上而下严格匹配;

           2,赋值兼容性原则在异常匹配中依然适用;

           3,一般而言:

                  1,匹配子类异常的 catch 放在上部;

                  2,匹配父类异常的 catch 放在下部;

                 

    4,纯虚的析构函数仅仅用来说明当前的类是抽象类,其它没有任何说明了;

    5,纯虚析构函数的实现:

           1,C++ 中规定纯虚函数不需要提供实现,等着子类实现;

           2,C++ 中规定,只要定义了析构函数,不管其是否为纯虚函数,一定要提供实现,因为在实现一个析构函数的时候,最后肯定要调用父类的析构函数,如果父类的析构函数是纯虚函数,并且这个纯虚函数没有具体实现,则调用到顶层父类的析构函数时没有实现,则更加奇怪,所以 C++ 语言规定了这个原则;

    6,现代 C++ 库必然包含必要的异常类族,异常类是数据结构类所依赖的“基础设施”,其成员关系为:

     

     

    7,异常类功能定义:

     

     

    8,异常类中的接口定义:

     

     

    9,异常类族创建:

    1,Exception.h 的创建:

      1 #ifndef EXCEPTION_H
      2 #define EXCEPTION_H
      3 
      4 #include "Object.h"
      5 
      6 namespace DTLib
      7 {
      8 
      9 #define THROW_EXCEPTION(e, m) (throw e(m, __FILE__, __LINE__))  //直接抛出异常对象,具体文件名和行号宏自己写出;当不能够用异常处理机制的时候,只需用在这里注释掉就可以了
     10 
     11 class Exception : public Object   // 设计为顶层的抽象类,没有对象,只能继承;
     12 {
     13 protected:
     14     char* m_message;
     15     char* m_location;
     16 void init(const char* message, const char* file, int line);
     17 
     18 public:
     19     Exception(const char* message);
     20     Exception(const char* file, int line);
     21     Exception(const char* message, const char* file, int line);
     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     virtual ~Exception() = 0;   //抽象类,析构函数用虚函数;纯虚函数的实现等着子类来完成;但凡定义析构函数,必须实现,因为析构函数时,必须要调用父类的析构函数。
     28 };
     29 
     30 class ArithmeticException : public Exception
     31 {
     32 public:
     33     ArithmeticException() : Exception(0){}
     34     ArithmeticException(const char* message) : Exception(message){}
     35     ArithmeticException(const char *file, int line) : Exception(file, line){}
     36     ArithmeticException(const char* message, const char* file, int line) : Exception(message, file, line){}
     37     ArithmeticException(const ArithmeticException& e) : Exception(e) {}
     38     ArithmeticException& operator =(const ArithmeticException& e)
     39     {
     40         Exception::operator =(e);
     41 
     42         return *this;
     43     }
     44 };
     45 
     46 class NullPointerException : public Exception
     47 {
     48 public:
     49     NullPointerException() : Exception(0){}
     50     NullPointerException(const char* message) : Exception(message){}
     51     NullPointerException(const char *file, int line) : Exception(file, line){}
     52     NullPointerException(const char* message, const char* file, int line) : Exception(message, file, line){}
     53     NullPointerException(const NullPointerException& e) : Exception(e) {}
     54     NullPointerException& operator =(const NullPointerException& e)
     55     {
     56         Exception::operator =(e);
     57 
     58         return *this;
     59     }
     60 };
     61 
     62 class IndexOutOfBoundsException : public Exception
     63 {
     64 public:
     65     IndexOutOfBoundsException() : Exception(0){}
     66     IndexOutOfBoundsException(const char* message) : Exception(message){}
     67     IndexOutOfBoundsException(const char *file, int line) : Exception(file, line){}
     68     IndexOutOfBoundsException(const char* message, const char* file, int line) : Exception(message, file, line){}
     69     IndexOutOfBoundsException(const IndexOutOfBoundsException& e) : Exception(e) {}
     70     IndexOutOfBoundsException& operator =(const IndexOutOfBoundsException& e)
     71     {
     72         Exception::operator =(e);
     73 
     74         return *this;
     75     }
     76 };
     77 
     78 class NoEnoughMemoryException : public Exception
     79 {
     80 public:
     81     NoEnoughMemoryException() : Exception(0){}
     82     NoEnoughMemoryException(const char* message) : Exception(message){}
     83     NoEnoughMemoryException(const char *file, int line) : Exception(file, line){}
     84     NoEnoughMemoryException(const char* message, const char* file, int line) : Exception(message, file, line){}
     85     NoEnoughMemoryException(const NoEnoughMemoryException& e) : Exception(e) {}
     86     NoEnoughMemoryException& operator =(const NoEnoughMemoryException& e)
     87     {
     88         Exception::operator =(e);
     89 
     90         return *this;
     91     }
     92 };
     93 
     94 class InvalidParameterException : public Exception
     95 {
     96 public:
     97     InvalidParameterException() : Exception(0){}
     98     InvalidParameterException(const char* message) : Exception(message){}
     99     InvalidParameterException(const char *file, int line) : Exception(file, line){}
    100     InvalidParameterException(const char* message, const char* file, int line) : Exception(message, file, line){}
    101     InvalidParameterException(const InvalidParameterException& e) : Exception(e) {}
    102     InvalidParameterException& operator =(const InvalidParameterException& e)
    103     {
    104         Exception::operator =(e);
    105 
    106         return *this;
    107     }
    108 };
    109 
    110 class InvalidOperationException : public Exception
    111 {
    112 public:
    113     InvalidOperationException() : Exception(0){}
    114     InvalidOperationException(const char* message) : Exception(message){}
    115     InvalidOperationException(const char *file, int line) : Exception(file, line){}
    116     InvalidOperationException(const char* message, const char* file, int line) : Exception(message, file, line){}
    117     InvalidOperationException(const InvalidOperationException& e) : Exception(e) {}
    118     InvalidOperationException& operator =(const InvalidOperationException& e)
    119     {
    120         Exception::operator =(e);
    121 
    122         return *this;
    123     }
    124 };
    125 
    126 }
    127 
    128 #endif // EXCEPTION_H

    2,Exception.cpp的创建:

     1 #include "Exception.h"
     2 #include <cstring>
     3 #include <cstdlib>
     4 
     5 using namespace std;
     6 
     7 namespace DTLib
     8 {
     9 
    10 void Exception::init(const char* message, const char* file, int line)
    11 {
    12    m_message = (message ? strdup(message) : NULL);  // 将message复制一份指向堆空间,而内容相同;保证是独立的堆空间;采用三目运算符因为 message 可能为空但是 strdup 没有判断为空的情况;
    13 
    14     if( file != NULL)
    15     {
    16         char sl[16] = {0};
    17 
    18         itoa(line, sl, 10);     //这里不懂
    19 
    20         m_location = static_cast<char*>(malloc(strlen(file) + strlen(sl) + 2));  // 加上冒号和结束符;
    21 
    22         if( m_location != NULL )  // 对于 DTLib 里面的类的话,动态申请后一定要判断是否为空指针,这里不再做为空的异常处理,免得陷入死循环
    23         {
    24             m_location = strcpy(m_location, file);
    25             m_location = strcat(m_location, ":");
    26             m_location = strcat(m_location, sl);
    27         }
    28     }
    29     else
    30     {
    31         m_location = NULL;  // 这里已经做了 m_location 为空的准备;
    32     }
    33 }
    34 
    35 Exception::Exception(const char* message)
    36 {
    37     init(message, NULL, 0);
    38 }
    39 
    40 Exception::Exception(const char* file, int line)
    41 {
    42     init(NULL, file, line);
    43 }
    44 
    45 Exception::Exception(const char* message, const char* file, int line)
    46 {
    47     init(message, file, line);
    48 }
    49 
    50 Exception::Exception(const Exception& e)  //深拷贝,必须实现
    51 {
    52     m_message = strdup(e.m_message);    // 保证是独立的堆空间;
    53     m_location = strdup(e.m_location);
    54 }
    55 
    56 Exception& Exception::operator= (const Exception& e)//深拷贝,必须实现
    57 {
    58     if( this != &e)
    59     {
    60         free(m_message);
    61         free(m_location);
    62 
    63         m_message = strdup(e.m_message);    // 保证是独立的堆空间;
    64         m_location = strdup(e.m_location);
    65 }
    66 
    67     return *this;
    68 }
    69 
    70 const char* Exception::message() const
    71 {
    72     return m_message;
    73 }
    74 
    75 const char* Exception::location() const
    76 {
    77     return m_location;
    78 }
    79 
    80 Exception::~Exception()
    81 {
    82     free(m_message);
    83     free(m_location);
    84 }

    10,设计原则:

           1,在可复用代码库设计时,尽量使用面相对象技术进行架构;

           2,尽量使用异常处理机制分离正常逻辑和异常逻辑;

    11,小结:

      1,现代 C++ 库必然包含必要的异常类族;

      2,所有库中的数据结构都依赖于异常机制;

      3,异常机制能够分离库中代码的正常逻辑和异常逻辑;

  • 相关阅读:
    编程题目: PAT 1012. 数字分类 (20)
    编程题目: PAT 1011. A+B和C (15)
    Poj3683(2-set
    LightOJ 1427(AC自动机
    UVA 11990(BIT套treap
    网络流汇总....
    10月——备战区域赛
    去掉ubuntu的文件管理器中“位置”栏里的无用标签
    Poj 2104(主席树入门
    Poj 1568(极大极小搜索
  • 原文地址:https://www.cnblogs.com/dishengAndziyu/p/10920566.html
Copyright © 2011-2022 走看看