异常类构建
异常的类型可以是自定义类类型
对于类类型异常的匹配依旧是从上到下严格的匹配
赋值兼容性原则在异常匹配中依然适用
一般而言
-匹配子类异常的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. 利用Fiddler对Jmeter的请求进行抓包

    前言 有时候,为了得到更详细的请求结果,我们可能需要使用Fiddler结合Jmeter来抓包分析,从而更好的辅助测试. 遇到的问题 这里以一个获取学生信息的接口为例进行说明. 当我在Jmeter里按接 ...

  2. net.sf.json将string转为map

    背景 改一个以前的项目,项目里只有这个包,虽然我想用gson或者fastjson,然而并不想引入新的jar.于是使用这个,特此记录,感觉贼不好用. 实现代码 entity.getData()的值:{a ...

  3. SpringBoot系列——Jackson序列化

    前言 Spring Boot提供了与三个JSON映射库的集成: Gson Jackson JSON-B Jackson是首选的默认库. 官网介绍: https://docs.spring.io/spr ...

  4. vs2017 C# ActiveX浏览器插件 创建 发布 C# windows窗体控件库(.NET Framework)注意事项

    vs2017需要安装插 插件下载地址:https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.Micro ...

  5. MongoDB(一):NoSQL简介、MongoDB简介

    1. NoSQL简介 1.1 什么是NoSQL NoSQL(NoSQL= Not Only SQL),意即“不仅仅是SQL",是一项全新的数据库理念,泛指非关系型的数据库. 1.2 为什么需 ...

  6. Add the Scheduler Module 添加计划程序模块

    Important 重要 Scheduler requires the Event business class to be in your XAF application model. Follow ...

  7. Axure制作dialog效果的动作步骤

    1.在Axure中添加一个弹框按钮  2.将动态面版拖动到界面中    3.双击动态面版,双击state  4.拖入一块图片占位符进来    5.设置图片  6.回到上一个界面设置动态面版的大小,使其 ...

  8. dpwwn:2 Vulnhub Walkthrough

    此镜像配置了静态IP地址:10.10.10.10,需要调整下网络 主机层扫描: ╰─ nmap -p1-65535 -sV -A 10.10.10.10 80/tcp    open  http    ...

  9. 团队项目之Scrum5

    小组:BLACK PANDA 时间:2019.11.25   每天举行站立式会议 提供当天站立式会议照片一张 2 昨天已完成的工作 2 实现文章展示页面 完善后台的编辑功能接口 今天计划完成的工作 2 ...

  10. 字符串 string方法

    字符串 name = 'ab c dd' i = name.find('a', 1, 3) # 找到返回对应下标 找不到返回-1 print(i) j = name.rfind('d') # 寻找对应 ...