异常类的构建(四)

我们在之前学习了 C++ 中有关异常的知识,现在我们来重新回顾下。那么异常的格式是什么呢?便是 try ... catch ...;try 语句处理正常的代码逻辑,而 catch 语句则处理异常情况,try 语句中的异常由对应的 catch 语句处理。格式如下

try
{
    double r = divide(1, 0);
}
catch(...)
{
    cout << "Divided by zero ..." << endl;
}

在 C++ 中,通过 throw 语句抛出异常信息。throw 抛出的异常必须被 catch 处理,当前函数如果能处理异常,程序将继续往下执行;如果当前函数无法处理异常则函数停止执行并返回。未被处理的异常会顺着函数调用栈向上传播,直到被处理为止,否则程序将停止执行。如下

同一个 try 语句可以跟上多个 catch 语句。catch 语句可以定义具体处理的异常类型,不同类型的异常由不同的 catch 语句负责处理;try 语句中可以抛出任何类型的异常,catch(...) 用于处理所有类型的异常,任何异常都只能被捕获(catch)一次。异常处理的匹配规则如下

异常的类型可以是自定义类类型,对于类类型异常的匹配依旧是至上而下严格匹配,赋值兼容性原则在异常匹配中依然适用。一般而言:匹配子类异常的 catch 放在上部,匹配父类异常的 catch 放在下部。现代 C++ 库中必然包含充要的异常类族,因为异常类是数据结构类所依赖的“基础设施”!举个例子,如果我们在申请内存失败时便要但会一个内存不足的异常。异常类如下图所示

下来我们来看看异常类功能定义,如下

下来我们来创建一个异常类族,代码如下

Exception.h 源文件

#ifndef EXCEPTION_H#define EXCEPTION_H

#include "Object.h"

namespace DTLib
{

class Exception : public Object
{
private:
    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();
};

#endif // EXCEPTION_H

Exception.cpp 源码如下

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

using namespace std;

namespace DTLib
{

void Exception::init(const char* message, const char* file, int line)
{
    m_message = strdup(message);

    if( file != NULL )
    {
        char s1[16] = {0};

        itoa(line, s1, 10);

        m_location = static_cast<char*>(malloc(strlen(file) + strlen(s1) + 2));
        m_location = strcpy(m_location, file);
        m_location = strcat(m_location, ":");
        m_location = strcat(m_location, s1);
    }
    else
    {
        m_location = NULL;
    }
}

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

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_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("test", __FILE__, __LINE__);
    }
    catch(const Exception& e)
    {
        cout << "catch(const Exception& e)" << endl;
        cout << e.message() << endl;
        cout << e.location() << endl;
    }

    return 0;
}

下来我们来看看编译结果

我们看到抛出了一个异常,它的文件名是 test,行号是 11 行。我们可以在 Exception.h 头文件添加一个宏,用来显示文件名及行号,定义如下

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

然后将 mian.cpp 中的 throw 语句中的抛异常改为下面这样

THROW_EXCEPTION(Exception, "test");

编译结果如下

我们看到效果是一样的。那么在可复用代码库设计时,尽量使用卖你想对象技术进行架构,尽量使用异常处理机制分类正常逻辑和异常逻辑。通过今天对异常类的学习,总结如下:1、C++ 中国直接支持异常处理的概念,try ... catch ... 是 C++ 中异常处理的专用语句;2、try 语句处理的是正常代码逻辑,catch 语句处理的是异常情况;3、同一个 try 语句可以跟上多个 catch 语句,异常处理必须严格匹配,不进行任何的类型转换;4、现代 C++ 库必然包含充要的异常类族,所有库中的数据结构都依赖于异常机制;5、异常机制能够分离库中代码的正常逻辑个异常逻辑。

欢迎大家一起来学习数据结构,可以加我QQ:243343083。

原文地址:http://blog.51cto.com/12810168/2156990

时间: 2024-07-29 11:13:45

异常类的构建(四)的相关文章

第十一课、异常类的构建-------------狄泰软件学院

一.自定义异常类 1.异常的类型可以是自定义的类类型 2.对于类类型的匹配依旧是之上而下的严格匹配 3.赋值兼容性原则在异常匹配中依然适用 所以要 (1).匹配子类异常的catch放在上部 (2).匹配父类异常的catch放在下部 4.异常类是数据结构所依赖的"基础设施"(现代c++库也必然包含充要的异常类族) 二.一步步打造自己的异常类 1.首先是抽象类EXception的编写,既然是抽象类,必然含有纯虚函数,通常的做法都是将析构函数作为纯虚函数 头文件:接口定义 class Exc

异常类的构建

1.Exception.h 中增加ArithmetricException类 class ArithmetricException:public Exception { public: ArithmetricException():Exception(0) {} //我认为这个实现没有必要 ArithmetricException(const char* message):Exception(message) {} ArithmetricException(const char* file, i

Core Java 经典笔试题总结(异常类问题)

所有代码均在本地编译运行测试,环境为 Windows7 32位机器 + eclipse Mars.2 Release (4.5.2) 2016-10-17 整理 下面的代码输出结果是多少?为什么?并由此总结几个编程规范. 1 class smallT { 2 public static void main(String args[]) { 3 smallT t = new smallT(); 4 int b = t.get(); 5 System.out.println(b); 6 } 7 8

跟王老师学异常(三)异常类的继承体系

异常类的继承体系 主讲人:王少华  QQ群号:483773664 学习目标: 1.掌握异常的体系 2.掌握处理异常类的几中常用方法 一.异常类继承体系图 Java提供了丰富的异常类,这些异常类之间有严格的继承关系,如下图所示 从上图可以看出,Java把所有非正常情况分成两种,一种是异常(Exception),另一种是错误(Error),它们都继承Throwable父类. 二.Error Error错误,一般是指虚拟机相关的问题.即仅靠程序本身无法恢复的严重错误.如系统崩溃.虚拟机出错误.动态链接

C#异常类相关总结

C#异常类相关总结 在做异常处理的时候,最好能在应用程序所有的入口处(事件处理函数,主函数,线程入口)使用try-catch. 但是不要在程序构造函数入口处添加try-catch,因为此处产生异常,它自己并没有能力来处理,因为它还没有构造完毕,只能再向外层抛出异常. C#异常类一.基类Exception C#异常类二.常见的异常类 1.SystemException类:该类是System命名空间中所有其他异常类的基类.(建议:公共语言运行时引发的异常通常用此类) 2.ApplicationExc

Cpp数据结构实战开发2-基本类的构建

构建自己的类库,MxLib 迭代开发 单一继承树:所有类继承自Object类,规范堆对象创建时的行为 只抛异常,不处理:使用宏抛出异常,提高可移植性 弱耦合性:尽量不使用标准库中的类和函数,提高可移植性 顶层父类 软件架构实践经验: 尽量使用单重继承的方式进行系统设计 尽量保持系统中只存在单一的继承树 尽量使用组合关系代替继承关系 在MxLib中创建Objec类,所有类都继承自MxLib::Object类,统一定义动态内存申请和销毁的行为 头文件 Object.h #ifndef OBJECT_

Java学习(异常类)

一.什么是异常: 异常就是在运行时产生的问题.通常用Exception描述. 在java中,把异常封装成了一个类,当出现问题时,就会创建异常类对象并抛出异常相关的信息(如详细信息,名称以及异常所处的位置). 二.异常的继承关系: Throwable类是所有错误跟异常类的超类(祖宗类). Exception异常类及其子类都是继承自Throwable类,用来表示java中可能出现的异常,并且合理的处理这些异常. RuntimeException类是运行异常类,继承自Exception类,它以及它的子

python代理池的构建1——代理IP类的构建,以及配置文件、日志文件、requests请求头

一.整体结构 二.代理IP类的构建(domain.py文件) ''' 实现_ init_ 方法, 负责初始化,包含如下字段: ip: 代理的IP地址 port:代理IP的端口号 protocol: 代理IP支持的协议类型,http是0, https是1, https和http都支持是2 nick_ type: 代理IP的匿名程度,高匿:0,匿名: 1,透明:2 speed:代理IP的响应速度,单位s area:代理IP所在地区 score:代理IP的评分,用于衡量代理的可用性;默认分值可以通过配

Asp.net Core WebApi 全局异常类

通过全局异常类,所有程序中遇到的错误都会被拦截,并友好的返回结果. 1.自定义一个全局异常处理类中间件 using Microsoft.AspNetCore.Http; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Threading.Tasks; using Syst