数据结构之异常类

配套环境

clion + mingw

设计要求

异常的类型可以是自定义类类型

对于类类型异常的匹配依旧是自上而下严格匹配

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

一般而言: 匹配子类异常的catch放在上部

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

设计方案

实现代码

Exception.cpp

#include "Exception.h"
#include <cstring>
#include <cstdlib>
using  namespace std;

namespace DTLib {
    void Exception::init(const char *message, const char *file, int line) {
        m_message = _strdup(message);
        if(file != NULL){
            char sl[16] = {0};
            itoa(line, sl, 10);
            m_location = static_cast<char*>(malloc(strlen(file) + strlen(sl) + 2));
            m_location = strcpy(m_location, file);
            m_location = strcat(m_location, ":");
            m_location = strcat(m_location, sl);
        }else{
            m_location = NULL;
        }
    }

    Exception::Exception(const char *message){
        init(message, NULL, 0);
    }

    Exception::Exception(const char *file, int line){
        init(NULL, file, line);
    }

    Exception::Exception(const char *message, const char *file, int line){
        init(message, file, line);
    }

    Exception::Exception(const Exception &e){
        m_message = strdup(e.m_message);
        m_location = strdup(e.m_location);
    }

    Exception& Exception:: operator=(const Exception &e){
        if(this != &e){
            free(m_message);
            free(m_location);
            m_message = strdup(e.m_message);
            m_location = strdup(e.m_location);
        }
        return *this;
    }
    const char *Exception::message() const{
        return m_message;
    }
    const char *Exception::location() const{
        return m_location;
    }
    Exception::~Exception(){
        free(m_message);
        free(m_location);
    }
} // namespace DTLib

Exception.h

#ifndef EXCEPTION_H
#define EXCEPTION_H
#include <cstring>

namespace DTLib {
#define THROW_EXCEPTION(e,m) (throw e(m, __FILE__, __LINE__))
    class Exception {
    protected:
        char *m_message;
        char *m_location;
        void init(const char *message, const char *file, int line);

    public:
        Exception(const char *message);
        Exception(const char *file, int line);
        Exception(const char *message, const char *file, int line);

        Exception(const Exception &e);
        Exception &operator=(const Exception &e);

        virtual const char *message() const;
        virtual const char *location() const;

        virtual ~Exception() = 0;
    };

    class ArithmeticException : public Exception{
    public:
       ArithmeticException() : Exception(NULL){}
       ArithmeticException(const char * message) : Exception(message){}
       ArithmeticException(const char * file, int line) : Exception(file, line){}
       ArithmeticException(const char * message, const char* file, int line) : Exception(message, file, line){}

       ArithmeticException(const ArithmeticException& e) : Exception(e){}

       ArithmeticException& operator=(const ArithmeticException& e){
           Exception::operator=(e);
           return *this;
       }

    };

    class NullPointerException : public Exception{
    public:
       NullPointerException() : Exception(NULL){}
       NullPointerException(const char * message) : Exception(message){}
       NullPointerException(const char * file, int line) : Exception(file, line){}
       NullPointerException(const char * message, const char* file, int line) : Exception(message, file, line){}

       NullPointerException(const NullPointerException& e) : Exception(e){}

       NullPointerException& operator=(const NullPointerException& e){
           Exception::operator=(e);
           return *this;
       }

    };

    class IndexOutOfBoundsException : public Exception{
    public:
       IndexOutOfBoundsException() : Exception(NULL){}
       IndexOutOfBoundsException(const char * message) : Exception(message){}
       IndexOutOfBoundsException(const char * file, int line) : Exception(file, line){}
       IndexOutOfBoundsException(const char * message, const char* file, int line) : Exception(message, file, line){}

       IndexOutOfBoundsException(const IndexOutOfBoundsException& e) : Exception(e){}

       IndexOutOfBoundsException& operator=(const IndexOutOfBoundsException& e){
           Exception::operator=(e);
           return *this;
       }

    };

    class NoEnoughMemoryException : public Exception{
    public:
       NoEnoughMemoryException() : Exception(NULL){}
       NoEnoughMemoryException(const char * message) : Exception(message){}
       NoEnoughMemoryException(const char * file, int line) : Exception(file, line){}
       NoEnoughMemoryException(const char * message, const char* file, int line) : Exception(message, file, line){}

       NoEnoughMemoryException(const NoEnoughMemoryException& e) : Exception(e){}

       NoEnoughMemoryException& operator=(const NoEnoughMemoryException& e){
           Exception::operator=(e);
           return *this;
       }

    };

    class InvalidParameterException : public Exception{
    public:
       InvalidParameterException() : Exception(NULL){}
       InvalidParameterException(const char * message) : Exception(message){}
       InvalidParameterException(const char * file, int line) : Exception(file, line){}
       InvalidParameterException(const char * message, const char* file, int line) : Exception(message, file, line){}

       InvalidParameterException(const InvalidParameterException& e) : Exception(e){}

       InvalidParameterException& operator=(const InvalidParameterException& e){
           Exception::operator=(e);
           return *this;
       }

    };
} // namespace DTLib

#endif

设计原则

在可复用代码库设计时,尽量使用面向对象技术进行架构,尽量使用异常处理机制分离正常逻辑和异常逻辑

小结

现代C++库必然包含充要的异常类族

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

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

喝水不忘挖井人: 更多内容请搜索狄泰软件学院(淘宝/B站)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Joyce_JTR

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值