异常类构建
异常的类型可以是自定义类类型
对于类类型异常的匹配依旧是从上到下严格的匹配
赋值兼容性原则在异常匹配中依然适用
一般而言
-匹配子类异常的catch放在上部
-匹配父类异常的catch放在下部

现代C++库必然包含充要的异常类族
异常类是数据结构类所依赖的基础设施

Exception是一个抽象类,不能定义对象,用来被继承。通过继承的方式,定义了5个异常类。
ArithmetricException:计算异常。例如1/0的错误
NullPointerException:空指针异常
IndexOutOfBoundsException:越界异常。访问数组的时候,有可能越界
NoEnoughMemoryException:内存不足异常。动态申请内存空间,没有充足的空间时
InvalidParameterException:参数错误异常。参数是否合法

异常类中的接口定义

class Exception
{
protected:
  char* m_message;
  char* m_location;
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
{
class Exception
{
protected:
char* m_location;
char* m_message;
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 ; //纯虚析构函数,纯虚函数需要提供实现吗?纯虚函数是不需要提供实现的,等待子类去实现。但是这个地方是个例外,C++规定只要自定义了析构函数,不管
//这个析构函数是不是纯虚函数,一定要提供实现。为什么?在析构一个对象的时候,最后肯定会调用到父类的析构函数,
}; } #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 = message; //直接进行这样的赋值,这样写可以吗?肯定不行,因为参数的message这个指针它指向的字符串有可能在栈上,有可能在堆空间中,还有可能在全局数据区。
//这样的话,没有办法控制message所指向的外部字符串的生命周期,所以说这样的写法是不安全的。可以拷贝一份字符串出来。
m_message = strdup(message); //将字符串复制到了堆空间。 if(file != NULL)
{
char sl[] = {};
itoa(line,sl,); //itoa在linux下是无法使用的,需要使用sprintf //m_location = malloc(strlen(file) + strlen(sl) + 2); //malloc函数返回的是void*,将void*直接赋值给char*是不可以的。因此需要进行强制类型转换。使用static_cast
m_location = static_cast<char*>(malloc(strlen(file) + strlen(sl) + ));
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,);
}
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_location = strdup(e.m_location);
m_message = strdup(e.m_message);
}
Exception& Exception::operator= (const Exception& e)
{
if(this != &e)
{
free(m_location);
free(m_message);
m_location = strdup(e.m_location);
m_message = strdup(e.m_message);
} return *this;
} const char* Exception::message() const
{
return m_message;
} const char* Exception::location() const
{
return m_location;
} Exception::~Exception()
{
free(m_location);
free(m_message);
}
}

main.cpp

#include <iostream>
#include "Exception.h" using namespace std;
using namespace DTLib; int main()
{
try
{
throw Exception("test", __FILE__,__LINE__); //将析构函数定义成了纯虚函数,是不能定义对象的,为了测试,先将纯虚去掉。
}
catch(const Exception& e)
{
cout << " catch(const Exception& e)" << endl;
cout << e.message() << endl;
cout << e.location() << endl;
}
return ;
}

进一步修改,在头文件中

namespace DTLib
{
#define THROW_EXCEPTION(e,m) (throw e(m, __FILE__,__LINE__)) class Exception

在main.cpp中这样使用

 try
{
THROW_EXCEPTION(Exception,"test"); //为了测试,还需要将纯虚特性去掉
}

使用这个宏的意义在于在需要的地方直接扔出相应的异常对象就可以了,具体的文件名和行号就不用去管了。

异常类的构建——顶层父类Exception的实现的更多相关文章

  1. python的异常处理及异常类定义

    python的异常处理语法和大多数语言相似: try: try块的语句... except exceptiontype1 as var:#使用as语句获得本次捕获到的异常的实例var except块语 ...

  2. 【转】【C#】异常类 Exception 枚举所有类型的异常

    一.基础 在C# 里,异常处理就是C# 为处理错误情况提供的一种机制.它为每种错误情况提供了定制的处理方式,并且把标识错误的代码与处理错误的代码分离开来. 对.NET类来说,一般的 异常类System ...

  3. 每天一点点java---继承exception类来实现自己的异常类

    package prac_1; /** * <p>Title: 捕获异常和实现自己的异常类</p> * <p>Description: 通过继承Exception类 ...

  4. C++异常第二篇---C++标准库异常类exception的使用

    1 继承图示 2 具体讲解 C++标准库异常类继承层次中的根类为exception,其定义在exception头文件中,它是C++标准库所有函数抛出异常的基类,exception的接口定义如下: na ...

  5. 2019-2-21.NET中异常类(Exception)

    .NET中异常类(Exception) 异常:程序在运行期间发生的错误.异常对象就是封装这些错误的对象. try{}catch{}是非常重要的,捕获try程序块中所有发生的异常,如果没有捕获异常的话, ...

  6. 借助backtrace和demangle实现异常类Exception

    C++的异常类是没有栈痕迹的,如果需要获取栈痕迹,需要使用以下函数: #include <execinfo.h> int backtrace(void **buffer, int size ...

  7. .NET中异常类(Exception)

    异常:程序在运行期间发生的错误.异常对象就是封装这些错误的对象. try{}catch{}是非常重要的,捕获try程序块中所有发生的异常,如果没有捕获异常的话,程序运行的线程将会挂掉,更严重的是这些错 ...

  8. 类的继承与super()的意义以即如何写一个正确的异常类

    这些东西都是我看了许多名师课程和自己研究的成果,严禁转载,这里指出了如何正确的自己定义一个异常类并看一看sun写的java的源代码话题一:子类的构造器执行是否一定会伴随着父类的构造执行? 1.this ...

  9. Java异常类(Throwable)

    一.异常类体系 二.异常类由来与定义 [异常类的由来]:Java把程序在运行时出现的各种不正常情况也看成了对象, 提取属性和行为进行描述,比如异常名称,异常信息,异常发生位置,从而形成了各种异常类 [ ...

随机推荐

  1. OSG嵌入QT的简明总结

    目录 1.解决方案 2.存在问题 1) 警告提示 2) 多线程问题 3) 其他 1.解决方案 不得不说关于OSG的资料实在太零散了,搜索了很多关于OSG在QT下的解决方案,都是各有各的说法,有的说的不 ...

  2. netty解决粘包半包问题

    前言:开发者用到TCP/IP交互时,偶尔会遇到粘包或者半包的数据,这种情况有时会对我们的程序造成严重的影响,netty框架为解决这种问题提供了若干框架 1. LineBasedFrameDecoder ...

  3. Git 自救指南

    Git 虽然因其分布式管理方式,不完全依赖网络,良好的分支策略,容易部署等优点,已经成为最受欢迎的源代码管理方式.但是一分耕耘一分收获,如果想更好地掌握 git,需要付出大量的学习成本.即使在各种 G ...

  4. 算法之冒泡排序手写之js写法andjava写法

    对于经典算法,你是否也遇到这样的情形:学时觉得很清楚,可过阵子就忘了? 本系列文章帮助你解决这个问题. 其实排序算法,仔细品读他的名字就见名知意了. 比如冒泡排序就很形象,遍历n次,每次循环相邻元素两 ...

  5. Data Guard:Oracle 12c –新增和更新的功能 (Doc ID 1558256.1)

    Data Guard: Oracle 12c – New and updated Features (Doc ID 1558256.1) APPLIES TO: Oracle Database - E ...

  6. Error:Cannot build artifact 'ssm:war exploded' because it is included into a circular dependency (artifact 'ssm:war exploded', artifact 'apinb-master:war exploded')

    打开 File->Project Structure –> Artifacts(ctrl+alt+shift+s) ,这里会有4个,我已经删除了,把 ssm:war 和 ssm:war e ...

  7. 22(7).模型融合---CatBoost

    一.Catboost简介 全称:Gradient Boosting(梯度提升) + Categorical Features(类别型特征) 作者:俄罗斯的搜索巨头Yandex 官方地址 论文链接 | ...

  8. Unable to open debugger port: java.net.SocketException

    网上都说是tomcat端口被占用,其实不是,这是因为文件权限不够,脚本不能执行,debug当然不能接受网络连接的数据 可以在Event Log里看到 所以只需要更改文件的级别就可以了(可读可写可执行) ...

  9. C++之封装继承和多态

    C++中非常重要的概念,尤其是相对于C语言而言,也是其具有如此高的工程使用性的重要原因. 封装 所谓封装是将某些东西隐藏起来,让外界无法直接使用,而必须通过某些特定的方式才能访问.也即是,将抽象得到的 ...

  10. IT兄弟连 HTML5教程 CSS3揭秘 CSS3属性1

    通过CSS选择器找到元素,就要使用CSS属性给找到的元素设置样式.尽管现在的浏览器已经支持了众多的CSS3属性,但作为初学者,最应该关注的就是一些“主流”的属性,如border-radius.box- ...