异常类构建

构建异常类的原因:因为当代的C++库基本上都会使用C++中的异常特性,依赖于异常创建出来的库稳定性非常好。
思路:C++中异常的类型可以是自定义类类型。

异常类的头文件:

#ifndef _EXCEPTION_H_
#define _EXCEPTION_H_

#include "Object.h"

namespace DTLib
{

#define THROW_EXCEPTION(e, m) (throw e(m, __FILE__, __LINE__))

    class Exception : public Object
    {
    protected:
        char* m_message;    // 说明当前异常的详细信息
        char* m_location;   // 说明发生异常的地点

        void Exception::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(0)    {   }
        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(0)   {   }
        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(0)  {   }
        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(0)    {   }
        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(0)  {   }
        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;
        }
    };

    // 非法操作异常
    class InvalidOperationException :public Exception
    {
    public:
        InvalidOperationException() : Exception(0)  {   }
        InvalidOperationException(const char* message) : Exception(message) {   }
        InvalidOperationException(const char* file, int line) : Exception(file, line)   {   }
        InvalidOperationException(const char* message, const char* file, int line) : Exception(message, file, line) {   }

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

        InvalidOperationException& operator=(const InvalidParameterException&e)
        {
            Exception::operator =(e);

            return *this;
        }
    };

}

#endif

异常类源文件:

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

#pragma warning(disable:4996)

namespace DTLib
{
    void Exception::init(const char* message, const char* file, int line)
    {
        m_message = (message ? strdup(message) : NULL);

        if (file != NULL) // 发生异常的文件名
        {
            char sl[16] = { 0 };
            itoa(line, sl, 10);

            m_location = static_cast<char*>(malloc(strlen(file) + strlen(sl) + 2)); // 2是 : \0

            if (m_location != NULL) 
            {
                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);
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值