我们经常会有这样的需求,异常或错误(又或者内存泄露时)发生时,如何进行快速定位,定位到文件一级、定位到函数一级、乃至定位到异常出现的行号一级。如此高大上的需求,只需要了解C++ preprocessor内置的一些宏定义如__FILE__(文件名),__LINE__(行号),以及boost\current_function.hpp 中的BOOST_CURRENT_FUNCTION(函数名),将这些宏定义以参数的形式传递给一个异常类,再施以一定的封装,便可轻松实现对异常出现位置的捕捉。

#include <exception>
#include <boost\shared_ptr.hpp>
#include <sstream>using namespace std;class Error :public exception
{
public:Error(const string& file, long line, const string& func, const string& msg);const char* what() const;           // 重写父类的what函数
private:string format(const string& file, long line,const string& func, const string& msg);boost::shared_ptr<string> _msg;   // 操作_msg, 如同操作一个string*
};Error::Error(const string& file, long line, const string& func, const string& msg)
{_msg = boost::shared_ptr<string>(new string(format(file, line, func, msg)));
}string format(const string& file, long line, const string& func, const string& msg)
{ostringstream oss;          // #include <sstream>oss << func << ":\n";oss << file << "(" << line << ").\n" << msg;return oss.str();
}const char* Error::what() const
{return _msg.c_str();
}

客户端程序:

double divide(double x, double y)
{if (y == 0.)throw Error(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, "除数不能为0");    // #include <boost\current_function.hpp>return x/y;
}
int main(int, char**)
{try{divide(1., 0.);}catch(exception& e){cout << e.what() << endl;}
}

C++预处理器也提供了如下的宏定义:

__DATE__
__TIME__

当然一种更常规的做法,利用宏定义(也只能用宏,而不可使用inline 内联函数取代,不由分说的原样替换虽然臭名昭著,却也有时非它不可)的原样替换的特性,对此做进一步的封装,避免显式传参的动作:

#define FAIL(msg)\
    std::ostringstream oss; \
    oss << msg; \
    throw Error(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, oss.str());#define ASSERT(predicate, msg)\
    if (!(predicate)) \
    {    \
        FAIL(msg);\
    }

这样客户端代码就可改写为:

double divide(double x, double y)
{if (y == 0.){FAIL("除数不能为0");    // 这一点要尤其注意,一定要将FAIL放在if判断的括号内部 // 如果不这样做的话,if 默认后面的一条语句作为你if判断成立时,要执行的动作// 这样FAIL宏原样替换的话,就无法识别oss << msg; 中的oss了}return x / y;
}

因为FAIL宏执行的动作是throw抛异常,如果不对之进行捕获的话,将由编译器进行捕获:

int main(int, char**)
{double x = 1., y = 0.;divide(x, y);return 0;
}

编译器将弹出如下窗口:

int main(int, char**)
{try{double x = 1., y = 0.;divide(x, y);}catch(exception& e){cout << e.what() << endl;}return 0;
}

或者我们使用断言的方式:

int main(int, char**)
{try{double x = 1., y = 0.;ASSERT(y != 0., "除数不能为0");}catch(exception& e){cout << e.what() << endl;}return 0;
}

C++基础::自制异常定位器相关推荐

  1. Java 语言基础(异常机制和File类,IO流,多线程,网络编程,反射机制)

    原文:Java 语言基础(异常机制和File类,IO流,多线程,网络编程,反射机制) 异常机制和File类 异常机制 基本概念 异常就是"不正常"的含义,在 Java 语言中主要指 ...

  2. Java基础知识——异常Throwable和Exception

    Java基础知识--异常Throwable和Exception Java设置了异常,旨在鼓励将方法中可能出现的异常告知给使用此方法的程序员(你和我!).当然了,这种方法是比较优雅的,让我们确切的知道是 ...

  3. 十九. Python基础(19)--异常

    十九. Python基础(19)--异常 1 ● 捕获异常 if VS异常处理: if是预防异常出现, 异常处理是处理异常出现 异常处理一般格式: try: <...............&g ...

  4. 【CXY】JAVA基础 之 异常概述

    概述: 1.异常给初学者的感觉(笔者当时就是这个感觉,不知道其他人是否有共鸣?) 1.异常是个什么东西?理解不了 2.很复杂 3.异常很"简陋",没什么用 4.我保证我写的程序正确 ...

  5. 【CXY】JAVA基础 之 异常

    讲述: 1.五个关键字 1.try:尝试捕获异常,具体的下面讲述 2.catch:当try捕获到异常了,系统会自动生成一个异常信息,这个异常信息就给catch,形象的说我抓住了这个异常. 3.thro ...

  6. java 抛出异常的作用_Java 基础之异常抛出

    Java 基础之异常抛出 Java,基础,异常抛出 在 Java 里,除了对异常的捕获外,你还可以抛出异常,还可以创造异常.抛出异常的作用就是告诉你的调用者,程序出现了不正常的情况了,得不要期望的结果 ...

  7. python14基础末异常文件

    1.异常的简介 ----程序在运行过程中可能会出现一些错误.比如: 使用了不存在的索引,两个不 同类型的数据相加-这些错误我们称之为异常 ----处理异常 程序运行时出现异常,目的并不是让我们的程序直 ...

  8. JavaSE---IO流基础(异常、File类、递归)

    6.IO流基础 6.1 异常 6.1.1 异常的概述 异常:就是程序在运行时出现不正常情况. 在Java中,将异常封装成了一个类:Throwable.Throwable下分为两大体系:Error和Ex ...

  9. Java基础:异常机制

    最近开始了找工作的面试,在面试过程中,面试官问了关于Java当中的异常处理机制,一直以来,无论写代码还是看书,自己对异常处理这一块就没有很好的重视过,对它的认知也仅仅停留在通过Try-catch去进行 ...

最新文章

  1. 叙述式教学方案计算机技术,计算机病毒及防治叙述式教学设计方案.doc
  2. [翻译]通过调用多个动作创建ASP.NET MVC视图
  3. php和python区别-python与php比较
  4. 中文乱码各个浏览器的处理
  5. 关于DataGridView_DataError事件的问题
  6. PHPstorm相同变量标识
  7. 送书 | 数据分析如烹小鲜
  8. Python案例:计算softmax函数值
  9. Java Web解决跨域请求,java初级面试笔试题
  10. java中的值传递与引用传递
  11. 最详细的联发科刷机教程MediaTek SP Flash Tool教程MTK通用驱动Windows 10 MTK VCOM USB Preloader Drivers
  12. 量子计算机慕课,计算机组成原理-中国大学mooc-题库零氪
  13. 2021-01-21安装FireFox插件FireBug和FirePath时遇到得坑(windows10)
  14. 搜电影和网盘资源网站
  15. 偏最小二乘法 Partial Least Squares
  16. 手机端 H5 语音识别转化为文字 demo
  17. 微信小程序 一键授权 给第三方平台代开发管理(一,创建第三方平台)
  18. 关于程序化交易 这篇文章说透了
  19. PhotonServer MMO游戏开发
  20. 钉钉电脑端屏蔽文件上传下载功能的方法

热门文章

  1. mysql5.6.4安装_win 7 64 mysql 5.6.4 安装
  2. linux 安装 xpdf csdn,Centos安装xpdf 解析pdf文件
  3. 2020.3二级中选择题文件类型题目全套
  4. img src请求后台值值能判断_图片src拼接后台返回ID
  5. Tensorflow精进之路(二):两层卷积神经网络模型训练MNIST
  6. C语言/C++基础知识代码整理
  7. java jtextfield 密码_Java Swing实战(三)文本组件JTextField和密码组件JPasswordField
  8. c++并发编程之thread::join()和thread::detach()(转)
  9. (转)sqoop常用命令http://www.cnblogs.com/cenyuhai/p/3306037.html
  10. 4.比赛F - Problem_F