c/c++语言开发共享C++实现并优化异常系统

c++原本的异常系统是这个样子的:调用what()方法时只返回异常的名称,并没有显示抛出异常的位置和堆栈跟踪,功能上显得少许的贫瘠…下面这个是我自己实现的改良版的异常处理系统:可以看到详细的信息,

c++原本的异常系统是这个样子的:

C++实现并优化异常系统

调用what()方法时只返回异常的名称,并没有显示抛出异常的位置和堆栈跟踪,功能上显得少许的贫瘠…

下面这个是我自己实现的改良版的异常处理系统:

C++实现并优化异常系统

可以看到详细的信息,下面是实现过程。

一、模拟栈展开的过程

网上看到别人用一些很奇怪的方法来获取堆栈信息,从而实现堆栈跟踪。

个人觉得很费劲,而且还要安装第三方库。

于是我们可以写一个类来模拟这个过程。

定义一个叫做exceptionstacktrace的类:

class exceptionstacktrace {  private:  	const char** m_message_trace = nullptr; // 方法名数组  	size_t* m_line_trace = nullptr; // 行数数组  	int m_top; // 栈顶      int m_size; // 大小  public:  	exceptionstacktrace(int size);  	void push(const char* message); // 入栈一个方法  	void pop(); // 出栈一个方法  	bool empty() const; // 判断是否为空  	int top() const; // 返回栈顶索引      int size() const; // 返回大小  	void print_stack_trace() const; // 打印堆栈跟踪信息  	void throw_(superexception except); // 抛出一个异常,需要继承superexception这个后面会讲到  };

既然是模拟,所以需要在程序最前面定义一个静态的对象,使用时在每一个函数的开始和结束部分加上这两句:

static exceptionstacktrace est = 128;  void method(...) {  	est.push(__funcsig__);      ... // 异常抛出在这里可以被捕捉  	est.pop();  }  main ...

当调用方法时,会在调用exceptionstacktrace的push方法,将方法信息压栈。

之后再执行方法内部的语句。

最后在将方法出栈,模拟方法已被调用完毕。

下面是实现代码:

exceptionstacktrace::exceptionstacktrace(int size) {      // 尺寸不能是负数  	if (size <= 0) throw std::exception("size should greater than 0.");  	m_message_trace = new const char*[size];  	m_top = 0;  	m_size = size;  }  void exceptionstacktrace::push(const char* message) {      // 方法信息压栈  	m_message_trace[m_top] = message;  	++m_top;  }  void exceptionstacktrace::pop() {      // 方法信息出栈,栈空抛异常  	if (this->empty()) throw std::exception("exception stack trace empty!");  	--m_top;  }  bool exceptionstacktrace::empty() const {  	return m_top == 0;  }  int exceptionstacktrace::top() const {  	return m_top;  }  int exceptionstacktrace::size() const {  	return m_size;  }  void exceptionstacktrace::print_stack_trace() const {      // 从后往前,因为栈的性质后进先出  	for (int i = m_top - 1; i >= 0; --i) {  		printf("   at method "%s"n", m_message_trace[i]);  	}  }  void exceptionstacktrace::throw_(superexception except) {      // 抛出一个异常  	printf("unhandled exception: %s: %sn", except.exception_name(), except.message());  	this->print_stack_trace();  	exit(-1);  }

二、新异常处理系统中异常的定义

异常包括信息和异常名称,同时还需要支持自定义异常。

所以我们可以搞一个用于新异常系统的父类异常,自定义的异常全部继承这个类即可。

父类的免费精选名字大全叫superexception,下面是类结构:

#define m_getname(data) #data // 宏定义,获取字符串形式类的名称  class superexception {  private:  	const char* m_exception_name = nullptr; // 异常名称  	const char* m_message = nullptr; // 异常消息  public:      // 构造函数  	superexception(const char* message, const char* exception_name = m_getname(superexception));  	const char* message() const; // 获取异常消息  	const char* exception_name() const; // 获取异常名称  };

然后是实现部分:

superexception::superexception(const char* message, const char* exception_name) {  	m_message = message;  	m_exception_name = exception_name;  }  const char* superexception::message() const {  	return m_message;  }  const char* superexception::exception_name() const {  	return m_exception_name;  }

具体用法:

int main() {  	est.push(__funcsig__);  	int i = 0;  	scanf_s("%d", &i);  	if (i == 128) est.throw_(superexception("这是一个异常。"));  	est.pop();  	return 0;  }

当输入128时:

C++实现并优化异常系统

三、超级运用

#include "exceptionstacktrace.h"  static exceptionstacktrace est = 128;  // 自定义一个异常  class indexoutofboundsexception : public superexception {  public:  	indexoutofboundsexception(const char* message, const char* exception_name = m_getname(exception))  		: superexception(message, exception_name) {  	}  };  // 自定义一个异常  class badarrayexception : public superexception {  public:  	badarrayexception(const char* message, const char* exception_name = m_getname(exception))  		: superexception(message, exception_name) {  	}  };  template<typename t> class array {  private:  	t* m_array;  	size_t m_length;  private:      // 下标检查  	void index_check(size_t index) {  		est.push(__funcsig__);  		if (index >= m_length) {  			est.throw_(indexoutofboundsexception("index out of bounds."));  		}  		est.pop();  	}  public:      // 构造器  	array(size_t length) {  		est.push(__funcsig__);  		m_length = length;  		try {  			m_array = new t[length];  		} catch (std::bad_alloc) {  			est.throw_(badarrayexception("cannot create a array object because no space."));  		}  		est.pop();  	}      // 索引访问  	t& operator[](size_t index) {  		est.push(__funcsig__);  		index_check(index);  		est.pop();  		return m_array[index];  	}  };  int main() {  	est.push(__funcsig__);  	array<void*> a = 128;  	a[129] = new char[16];  	est.pop();  	return 0;  }

结果:

C++实现并优化异常系统

为一的遗憾就是没法加上行号文件等提示信息,如果能够实现的话,我将会在下一篇博客中提及。

到此这篇关于c++实现并优化异常系统的文章就介绍到这了,更多相关c++异常系统内容请搜索<计算机技术网(www.ctvol.com)!!>以前的文章或继续浏览下面的相关文章希望大家以后多多支持<计算机技术网(www.ctvol.com)!!>!

需要了解更多c/c++开发分享C++实现并优化异常系统,都可以关注C/C++技术分享栏目—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/1207251.html

(0)
上一篇 2022年8月8日
下一篇 2022年8月8日

精彩推荐