【数据结构】11_异常类构建

  • 异常的类型可以是自定义类类型
  • 对于类类型异常的匹配依旧是至上而下严格匹配
  • 赋值兼容性原则在异常匹配中依然适用
  • 一般而言

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

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

异常类是数据结构类所依赖的”基础设施“!

image.png

异常类功能定义

异常类 功能定义
ArithmeticException 计算异常
NullPointerException 空指针异常
IndexOutOfBoundsException 越界异常
NoEnoughMemoryException 内存不足异常
InvalidParameterExcetion 参数错误异常

异常类的接口定义

class Exception
{
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();
};

编程实验:创建异常类族

文件:Exception.h

#ifndef EXCEPTION_H
#define EXCEPTION_H

namespace DTLib
{

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

class Exception
{
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();

protected:
    char *m_message = nullptr;
    char *m_location = nullptr;
};

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

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

    ArithmeticExcption &operator= (const ArithmeticExcption &e)
    {
        Exception::operator=(e);

        return *this;
    }
    ~ArithmeticExcption() override { }
};

class NullPointerException : public Exception
{
public:
    NullPointerException() : Exception(nullptr) { }
    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 ArithmeticExcption &e) : Exception(e) { }

    NullPointerException &operator= (const ArithmeticExcption &e)
    {
        Exception::operator=(e);

        return *this;
    }
    ~NullPointerException() override { }
};

class IndexOutOfBoundsException : public Exception
{
public:
    IndexOutOfBoundsException() : Exception(nullptr) { }
    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 ArithmeticExcption &e) : Exception(e) { }

    IndexOutOfBoundsException &operator= (const ArithmeticExcption &e)
    {
        Exception::operator=(e);

        return *this;
    }
    ~IndexOutOfBoundsException() override { }
};

class NoEnoughMemoryException : public Exception
{
public:
    NoEnoughMemoryException() : Exception(nullptr) { }
    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 ArithmeticExcption &e) : Exception(e) { }

    NoEnoughMemoryException &operator= (const ArithmeticExcption &e)
    {
        Exception::operator=(e);

        return *this;
    }
    ~NoEnoughMemoryException() override { }
};

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

    InvalidParameterExcetion(const ArithmeticExcption &e) : Exception(e) { }

    InvalidParameterExcetion &operator= (const ArithmeticExcption &e)
    {
        Exception::operator=(e);

        return *this;
    }
    ~InvalidParameterExcetion() override { }
};

}

#endif // EXCEPTION_H

文件:Exception.cpp

#include "Exception.h"

#include <cstring>
#include <cstdlib>

namespace DTLib
{

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

Exception::Exception(const char *file, int line) : Exception(nullptr, file, line)
{
}

Exception::Exception(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 = 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 = nullptr;
    }
}

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()
{
    delete m_message;
    delete m_location;
}

}

文件:main.cpp

catch (const ArithmeticExcption &e)
TEST
..\DTLib\main.cpp:13

设计原则

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

小结

  • 现在C++库必要包含充要的异常类族
  • 所有库中的数据结构都依赖于异常机制
  • 异常机制能够分离库中代码的正常逻辑和异常逻辑

以上内容整理于狄泰软件学院系列课程,请大家保护原创!

Image placeholder
junhong
未设置
  86人点赞

没有讨论,发表一下自己的看法吧

推荐文章
【数据结构】1_进阶高手的大门

理解程序的本质问题:为什么会有各种各样的程序存在?程序的本质是什么?程序是为了解决实际问题而存在的,从本质而言,程序是解决问题的步骤描述。一小步的进阶:理解实际问题 确认问题类型 如:数值计算,求最

【数据结构】 10_C++异常简介

C++内置了异常处理的语法元素try...catch... try语句处理正常代码逻辑 catch语句处理异常代码逻辑 try语句中的异常由对应的catch语句处理 try { doubler=

【数据结构】2_数据的艺术

程序设计的挑战 利用计算机解决现实生活中的问题 生活中的不同个体之间存在联系 用计算机程序描述生活中个体间的联系 问题:如何描述生活中的个体?数据的概念程序的操作对象,用于描述客观事物数据的特点 可以

【数据结构】3_程序设计的灵魂

学员间的对话 木暮:我发现三井真是牛,只用一行就实现了strlen 宫城:那么强!他是怎么做的呢? 木暮:不知道,我看了一下,没看懂。。。 宫城:牛人就是牛人啊! 问题:程序是否越短越好?是否别人看不

python set (集合)数据结构

set(集合)是一个非常有用的数据结构。它与列表(list)的行为类似,区别在于set不能包含重复的值。这在很多情况下非常有用。例如你可能想检查列表中是否包含重复的元素,你有两个选择,第一个需要使用f

Python入门教程_5. 数据结构

这个章节将更详细地描述一些你已经了解的内容,并且添加了一些新的内容。 5.1.深入列表对象 List数据类型包含更多的方法,下面是List对象包含的所有方法: list.append(*x*) 将一个

数据结构与算法分析——开篇以及复杂度分析

开篇 你也许已经发现了,工作了几年,原以为已经是一只老鸟。但看到刚参加工作的同事,你发现,原来自己一直在原地踏步。跟新人相比,你的唯一优势就是对业务更熟悉而已,别的就没有什么优势了。 怎样才能够让自己

数据结构与算法分析——开篇以及复杂度分析

开篇你也许已经发现了,工作了几年,原以为已经是一只老鸟。但看到刚参加工作的同事,你发现,原来自己一直在原地踏步。跟新人相比,你的唯一优势就是对业务更熟悉而已,别的就没有什么优势了。怎样才能够让自己更上

JavaScript 的数据结构和算法

现在有个还不是好的项目,未来会成为好的项目的项目想介绍给大家。传送门https://github.com/MasterShu/JavaScript-Da...这个是本人在维护的一个项目。主要是使用Ja

数据结构与算法分析——链表

链表链表是一种常见的数据结构,是一组有序的数据,每个链表中的数据项称为元素。它跟数组很像,二者对比学习会更容易理解和记忆。数组是内存中连续的一块,不会间断。链表在内存中不一定是连续的一块。如果内存只剩

数据结构与算法分析——队列

定义队列,和栈类似,也是一种操作受限的线性表数据结构。与栈结构不同的是,可以对队列2端操作,要求数据从一端进(入队),从另一端出(出队)。队列遵循"先进先出"的原则,即最先进队列的数据元素,同样要最先

数据结构与算法分析——栈

定义栈是一种操作受限的线性表,只支持在一端进行插入和删除操作(入栈和出栈)。后进先出、先进后出是它最大的特点。当某个数据集合只在一端插入和删除数据,并满足先进后出的特性时,就可以选择栈这种数据结构。实

java与数据结构

数组与链表数组 数组是数据结构中的基本模块之一 数组是一种基本的数据结构,用于按顺序存储元素的集合。但是元素可以随机存取,因为数组中的每个元素都可以通过数组索引来识别。 数组可以有一个或多个维度

redis数据结构(二) - 字符串

基于redis5.0的版本。字符串编码:字符串对象的编码可以是int,raw或者embstr。1.rawraw就是redisObject+sds,即redisObject的ptr指针指向一个sds对象

Redis的数据结构和内部编码

redis是单线程,一次只执行一条命令,那为什么可以这么快: 纯内存 非阻塞IO 避免线程切换和竞态消耗 在使用过程中要注意: 一次只运行一条命令 避免长(慢)命令,例如keys、flushall、f

第一章:数据结构绪论

[[数据结构-第1章]绪论目录 [1数据结构有什么用?] [2基本概念和术语] [3逻辑结构与存储结构] [3.1逻辑结构] [3.2存储结构] [4抽象数据类型] [4.1数据类型] [

TPC-C解析系列01_TPC-C benchmark测试介绍

作者:阳振坤2019.10导语:自从蚂蚁金服自研数据库OceanBase获得TPC-C测试第一名后,引起了行业内外大量关注,我们衷心的感谢大家对OceanBase的支持与厚爱,也虚心听取外界的意见和建

【Git入门5】Git远程仓库 - GitHub常用操作流程1_配置

=================================== 本地仓库和远程仓库是完全隔开的 代码存储在云端GitHub SSHkey验证身份使用场景:可以避免我们重复的输入密码,提高开发效

重启大法失效?详述Oracle11g因JDBC bug引发异常Library Cache Lock等待处理事件

墨墨导读:在Oracle11g版本中可能出现由于JDBCbug导致sql绑定变量无法共享,过期游标过多的情况,此时如果发生大量并发业务,很有可能造成异常librarycachelock等待事件,造成数

Java 异常的处理方式与自定义异常

课程推荐:Java开发工程师--学习猿地精品课程 一、前言Java集合系列已经讲完了,接下来我们来讲异常与多线程。 Java基础语法;面向对象和封装;常用API第一部分;继承与多态;常用API第二部分

双11这场新数据狂欢

在一片“接下来就要吃土”的悲鸣声中,一年一度的双11落下了帷幕。这个以购物为主题的新兴节日,风头已经不输给任何传统节日了。从宣传造势到预售再到正式活动,与双11有关的任何一个话题都是全社会的关注点,刺

那个“炫酷狂拽”的数据可视化利器AntV 11.22版全新发布啦

导读AntV是一个数据可视化项目,也是一个团队,蚂蚁金服数据可视化团队,一群有爱有梦的人,怀揣「让人们在数据世界里获得视觉化思考能力」的梦想前行,希望成就智能时代全球领先的数据可视化解决方案,满足与日

NAS与对象存储:谁是非结构化数据存储的最佳选择?

非结构化数据是增长最快的数据类型之一。随着企业日积月累地生成、收集和存储越来越多的数据,必然会带来一个问题:什么是存储非结构化数据的最佳方式?直白来说,非结构化数据就是不遵循传统数据库格式的数据,其结

GoWeb教程_11.0. 错误处理,调试和测试

我们经常会看到很多程序员大部分的"编程"时间都花费在检查bug和修复bug上。无论你是在编写修改代码还是重构系统,几乎都是花费大量的时间在进行故障排除和测试,外界都觉得我们程序员是设计师,能够把一个系

GoWeb教程_11.1. 错误处理

Go语言主要的设计准则是:简洁、明白,简洁是指语法和C类似,相当的简单,明白是指任何语句都是很明显的,不含有任何隐含的东西,在错误处理方案的设计中也贯彻了这一思想。我们知道在C语言里面是通过返回-1或