C++数据结构第11课、异常类构建

补充的知识:

1char * strdup(const char* s);					头文件:#include <cstring>

用途:在堆空间申请一段内存,并将指针 s 指向的内容拷贝一份放进去,然后返回堆空间的内存。例如:m_message = strdup(message),意思就是在堆空间申请一段内存,并将 message 里面的内容拷贝一份放进堆空间,m_message 指向堆空间,从而实现赋值。主要原因是不知道指针 s 指向的内容是在栈上还是在堆上。

char* itoa(int value, char *string,int radix);
2itoa(i, buffer, 10)								头文件:#include <cstdlib>

用途:把整数转换为字符串;i 代表整型,buffer 一般指整形数组,10指的是十进制

#include <iostream>
#include <cstdlib>
using namespace std;

int main()
{
    int line = 10;
    char str[10] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a'};
    itoa(line, str, 10);
    cout << str << endl;
    return 0;
}

在这里插入图片描述

异常类的构建

  • 异常的类型可以是自定义类型
  • 对于类类型的异常的匹配依旧是自上而下严格匹配
  • 赋值兼容性原则在异常匹配中依然适用(子类的异常对象可以被父类的 catch 抓住)
  • 一般而言
    — 匹配子类异常的 catch 放在上部
    — 匹配父类异常的 catch 放在下部

异常类功能定义:
在这里插入图片描述

  • 异常类中的接口定义
    在这里插入图片描述

Exception.h

#ifndef EXCEPTION_H
#define EXCEPTION_H

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(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;
    }
};
}

#endif // EXCEPTION_H

Exception.cpp

#include "Exception.h"
#include <cstring>
#include <cstdlib>

namespace DTLib
{

void Exception::init(const char* message, const char* file, int line)
{
    m_message = strdup(message);
    if(file != nullptr)
    {
        char sl[16] = {0};
        itoa(line, sl, 10);
        m_location = reinterpret_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 = nullptr;
    }
}

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

Exception::Exception(const char* file, int line)
{
    init(nullptr, 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);
}

}

main.cpp

#include <iostream>
#include "Exception.h"

using namespace std;
using namespace DTLib;

int main()
{
    try
    {
        THROW_EXCEPTION(ArithmeticException, "xiebs");
    }
    catch (const ArithmeticException& e)
    {
        cout << "catch (const ArithmeticException& e)" << endl;
        cout << e.message() << endl;
        cout << e.location() << endl;
    }
    catch (const Exception& e)
    {
        cout << "catch (const Exception& e)" << endl;
        cout << e.message() << endl;
        cout << e.location() << endl;
    }
    return 0;
}

在这里插入图片描述
设计原则:在可复用代码库设计时,尽量使用面向对象技术进行架构,尽量使用异常处理机制分离正常逻辑和异常逻辑。

纯虚函数一般不需要实现,等着子类给它实现。但是无论析构函数是不是纯虚函数,就一定要给它提供实现。存在纯虚函数就是抽象类,抽象类不能生成对象。

Exception 这个类是抽象类,下面的子类都不是抽象类。因为他们都默认提供了析构函数,相当于重写了析构函数。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值