C++基础::自制异常定位器
我们经常会有这样的需求,异常或错误(又或者内存泄露时)发生时,如何进行快速定位,定位到文件一级、定位到函数一级、乃至定位到异常出现的行号一级。如此高大上的需求,只需要了解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++基础::自制异常定位器相关推荐
- Java 语言基础(异常机制和File类,IO流,多线程,网络编程,反射机制)
原文:Java 语言基础(异常机制和File类,IO流,多线程,网络编程,反射机制) 异常机制和File类 异常机制 基本概念 异常就是"不正常"的含义,在 Java 语言中主要指 ...
- Java基础知识——异常Throwable和Exception
Java基础知识--异常Throwable和Exception Java设置了异常,旨在鼓励将方法中可能出现的异常告知给使用此方法的程序员(你和我!).当然了,这种方法是比较优雅的,让我们确切的知道是 ...
- 十九. Python基础(19)--异常
十九. Python基础(19)--异常 1 ● 捕获异常 if VS异常处理: if是预防异常出现, 异常处理是处理异常出现 异常处理一般格式: try: <...............&g ...
- 【CXY】JAVA基础 之 异常概述
概述: 1.异常给初学者的感觉(笔者当时就是这个感觉,不知道其他人是否有共鸣?) 1.异常是个什么东西?理解不了 2.很复杂 3.异常很"简陋",没什么用 4.我保证我写的程序正确 ...
- 【CXY】JAVA基础 之 异常
讲述: 1.五个关键字 1.try:尝试捕获异常,具体的下面讲述 2.catch:当try捕获到异常了,系统会自动生成一个异常信息,这个异常信息就给catch,形象的说我抓住了这个异常. 3.thro ...
- java 抛出异常的作用_Java 基础之异常抛出
Java 基础之异常抛出 Java,基础,异常抛出 在 Java 里,除了对异常的捕获外,你还可以抛出异常,还可以创造异常.抛出异常的作用就是告诉你的调用者,程序出现了不正常的情况了,得不要期望的结果 ...
- python14基础末异常文件
1.异常的简介 ----程序在运行过程中可能会出现一些错误.比如: 使用了不存在的索引,两个不 同类型的数据相加-这些错误我们称之为异常 ----处理异常 程序运行时出现异常,目的并不是让我们的程序直 ...
- JavaSE---IO流基础(异常、File类、递归)
6.IO流基础 6.1 异常 6.1.1 异常的概述 异常:就是程序在运行时出现不正常情况. 在Java中,将异常封装成了一个类:Throwable.Throwable下分为两大体系:Error和Ex ...
- Java基础:异常机制
最近开始了找工作的面试,在面试过程中,面试官问了关于Java当中的异常处理机制,一直以来,无论写代码还是看书,自己对异常处理这一块就没有很好的重视过,对它的认知也仅仅停留在通过Try-catch去进行 ...
最新文章
- 叙述式教学方案计算机技术,计算机病毒及防治叙述式教学设计方案.doc
- [翻译]通过调用多个动作创建ASP.NET MVC视图
- php和python区别-python与php比较
- 中文乱码各个浏览器的处理
- 关于DataGridView_DataError事件的问题
- PHPstorm相同变量标识
- 送书 | 数据分析如烹小鲜
- Python案例:计算softmax函数值
- Java Web解决跨域请求,java初级面试笔试题
- java中的值传递与引用传递
- 最详细的联发科刷机教程MediaTek SP Flash Tool教程MTK通用驱动Windows 10 MTK VCOM USB Preloader Drivers
- 量子计算机慕课,计算机组成原理-中国大学mooc-题库零氪
- 2021-01-21安装FireFox插件FireBug和FirePath时遇到得坑(windows10)
- 搜电影和网盘资源网站
- 偏最小二乘法 Partial Least Squares
- 手机端 H5 语音识别转化为文字 demo
- 微信小程序 一键授权 给第三方平台代开发管理(一,创建第三方平台)
- 关于程序化交易 这篇文章说透了
- PhotonServer MMO游戏开发
- 钉钉电脑端屏蔽文件上传下载功能的方法
热门文章
- mysql5.6.4安装_win 7 64 mysql 5.6.4 安装
- linux 安装 xpdf csdn,Centos安装xpdf 解析pdf文件
- 2020.3二级中选择题文件类型题目全套
- img src请求后台值值能判断_图片src拼接后台返回ID
- Tensorflow精进之路(二):两层卷积神经网络模型训练MNIST
- C语言/C++基础知识代码整理
- java jtextfield 密码_Java Swing实战(三)文本组件JTextField和密码组件JPasswordField
- c++并发编程之thread::join()和thread::detach()(转)
- (转)sqoop常用命令http://www.cnblogs.com/cenyuhai/p/3306037.html
- 4.比赛F - Problem_F