异常类的构建——顶层父类Exception的实现
异常类构建
异常的类型可以是自定义类类型
对于类类型异常的匹配依旧是从上到下严格的匹配
赋值兼容性原则在异常匹配中依然适用
一般而言
-匹配子类异常的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的实现的更多相关文章
- python的异常处理及异常类定义
python的异常处理语法和大多数语言相似: try: try块的语句... except exceptiontype1 as var:#使用as语句获得本次捕获到的异常的实例var except块语 ...
- 【转】【C#】异常类 Exception 枚举所有类型的异常
一.基础 在C# 里,异常处理就是C# 为处理错误情况提供的一种机制.它为每种错误情况提供了定制的处理方式,并且把标识错误的代码与处理错误的代码分离开来. 对.NET类来说,一般的 异常类System ...
- 每天一点点java---继承exception类来实现自己的异常类
package prac_1; /** * <p>Title: 捕获异常和实现自己的异常类</p> * <p>Description: 通过继承Exception类 ...
- C++异常第二篇---C++标准库异常类exception的使用
1 继承图示 2 具体讲解 C++标准库异常类继承层次中的根类为exception,其定义在exception头文件中,它是C++标准库所有函数抛出异常的基类,exception的接口定义如下: na ...
- 2019-2-21.NET中异常类(Exception)
.NET中异常类(Exception) 异常:程序在运行期间发生的错误.异常对象就是封装这些错误的对象. try{}catch{}是非常重要的,捕获try程序块中所有发生的异常,如果没有捕获异常的话, ...
- 借助backtrace和demangle实现异常类Exception
C++的异常类是没有栈痕迹的,如果需要获取栈痕迹,需要使用以下函数: #include <execinfo.h> int backtrace(void **buffer, int size ...
- .NET中异常类(Exception)
异常:程序在运行期间发生的错误.异常对象就是封装这些错误的对象. try{}catch{}是非常重要的,捕获try程序块中所有发生的异常,如果没有捕获异常的话,程序运行的线程将会挂掉,更严重的是这些错 ...
- 类的继承与super()的意义以即如何写一个正确的异常类
这些东西都是我看了许多名师课程和自己研究的成果,严禁转载,这里指出了如何正确的自己定义一个异常类并看一看sun写的java的源代码话题一:子类的构造器执行是否一定会伴随着父类的构造执行? 1.this ...
- Java异常类(Throwable)
一.异常类体系 二.异常类由来与定义 [异常类的由来]:Java把程序在运行时出现的各种不正常情况也看成了对象, 提取属性和行为进行描述,比如异常名称,异常信息,异常发生位置,从而形成了各种异常类 [ ...
随机推荐
- python批量插入数据到es和读取es数据
一.插入数据 1.首先准备类似如下数据 {"_type": "type1", "_id": 1, "_index": & ...
- [debug] 解决新建项目属性中没有 c\c++
写一些代码(不写不行),然后生成,然后就可以看到这个选项了
- MongoDB(一):NoSQL简介、MongoDB简介
1. NoSQL简介 1.1 什么是NoSQL NoSQL(NoSQL= Not Only SQL),意即“不仅仅是SQL",是一项全新的数据库理念,泛指非关系型的数据库. 1.2 为什么需 ...
- C#调试程序——断点+几种观察数据的方法
目录 C#调试程序--断点+观察数据的方法 1.写本文的背景 2.调试与测试 3.断点调试 3.1 F10 3.2 F11 3.3 SHIFT+F11 4.监视 4.1 按照1方法打断点,单步调试. ...
- selectors模块的设计亮点
事件类型标志的选择 在selectors模块中的开头直接定义了事件类型的标志数字,选用的是(1 << 0)就是1代替EVENT_READ读操作:使用(1 << 1)就是2代替E ...
- TimeSpan的用法
TimeSpan的属性和方法: 下面的列表涵盖了其中的一部分: 属性: Add:与另一个TimeSpan值相加. Days: 返回用天数计算的TimeSpan值.Hours: 返回用小时计算的Time ...
- HTML入门(html基本文本标签+快捷键讲解以及基本html组成解释)
id 标签 功能 1 <hr /> 水平分割线 2 <br /> 强制让文本换行 3 <p>段落</p> 段落标签(自带换行效果) 4 < ...
- C#本地文件下载以及FTP文件服务下载(以Pdf文件为例)
一.C#实现本地文件下载 1.文件下载的路径 文件名称 以及文件下载之后要放的位置 这三个变量是必须要的 2.定义以下四个对象: FileWebRequest ftpWebRequest = nu ...
- Tornado 框架
Tronado为何物 Tornado全称Tornado Web Server,是一个用Python语言写成的Web服务器兼Web应用框架,由FriendFeed公司在自己的网站FriendFeed中使 ...
- Python装饰器(Decorators )
http://book.pythontips.com/en/latest/decorators.html 在<Built-in Functions(3.6)>和<Python上下文管 ...