自己设计C++完善的异常处理类

一个相对完善的异
【菜科解读】
如何写一个异常处理类是一个不太容易的事情,最近刚好接触了一些不错的代码,看到了一些技巧,这里和大家分享一下。
一个相对完善的异常处理类(以及附加的一些东西)应该能够处理下面的一些功能:
1) 能够方便的定义异常类的继承树
2) 能够方便的throw、catch,也就是在代码中捕获、处理代码的部分应该更短
3) 能够获取异常出现的源文件的名字、方法的名字、行号
4) 能够获取异常出现的调用栈并且打印出来
由于目前我用的平台是linux,所以里面调用的一些函数也只是在linux下面有用。
Windows也肯定是具有相应的函数的,具体可能需要去查查
首先科普一些内容:
1) 对于没有捕获的异常(no handler),则会终止程序,调用terminate()
2) 在定义函数的时候,我们可以在定义的后面加上throw (exception1, exception2…):
a) 如果没有写这一段、则可能抛出任意的异常
b) 如果写throw(),则表示函数不能抛出任意的异常
c) 如果写throw(A, B), 表示函数抛出A、B的异常
如果抛出的异常不在列表范围内,则异常不能被catch,也就会调用terminate()
我们构想一下我们定义、调用我们的异常类的时候是怎样的一个情形:
1) 定义:
1:class DerivedException : public BaseException
2: {
3:public:
4: MY_DEFINE_EXCEPTION(DerivedException, BaseException);
5: };
2) 如何抛出异常
1: MY_THROW(DerivedException)
3) 如何catch异常
1:catch (DerivedException& e)
2: {
3: cout
5:#include
6:
7:#define MY_THROW(ExClass, args...) \
8:do \
9: { \
10: ExClass e(args); \
11: e.Init(__FILE__, __PRETTY_FUNCTION__, __LINE__); \
12:throw e; \
13: } \
14:while (false)
15:
16:#define MY_DEFINE_EXCEPTION(ExClass, Base) \
17: ExClass(const std::string& msg = "") throw() \
18: : Base(msg) \
19: {} \
20: \
21: ~ExClass() throw() {} \
22: \
23:/* override */ std::string GetClassName() const \
24: { \
25:return #ExClass; \
26: }
27:
28:class ExceptionBase : public std::exception
29: {
30:public:
31: ExceptionBase(const std::string& msg = "") throw();
32:
33:virtual ~ExceptionBase() throw();
34:
35:void Init(constchar* file, constchar* func, int line);
36:
37:virtual std::string GetClassName() const;
38:
39:virtual std::string GetMessage() const;
40:
41:constchar* what() constthrow();
42:
43:const std::string& ToString() const;
44:
45: std::string GetStackTrace() const;
46:
47:protected:
48: std::string mMsg;
49:constchar* mFile;
50:constchar* mFunc;
51:int mLine;
52:
53:private:
54:enum { MAX_STACK_TRACE_SIZE = 50 };
55:void* mStackTrace[MAX_STACK_TRACE_SIZE];
56: size_t mStackTraceSize;
57:mutable std::string mWhat;
58: };
59:
60:class ExceptionDerived : public ExceptionBase
61: {
62:public:
63: MY_DEFINE_EXCEPTION(ExceptionDerived, ExceptionBase);
64: };
65:
66:#endif
这个头文件首先定义了两个宏,这里先暂时不管他,我先来解释一下ExceptionBase,它继承自std::exception,std::exception里面其实已经提供了一些功能了,但是比较弱,为了实现我们上文提到的功能,这里只是继承了std:exception的借口,也就是what()函数。
上面的接口应该比较好理解,45行的GetStackTrace是打印当前的调用栈,49-51行分别存储了当前出现exception的源文件名,函数名,行号,54行定义了最大的调用栈显示的深度,也就是显示50行。
60行显示了怎样定义一个新的异常类,这个就很方便了,通过MY_DEFINE_EXCEPTION宏去定义了一个继承类,详情见16行,这里不再细说,我这里想说说7行的MY_THROW宏,使用了3个内置的参数,__FILE__, __LINE__, __PRETTY_FUNCTION__, 他们分别是当前的文件名,行号,和函数名,他们的使用方法是在哪儿出现,其相应的值就是什么。
为什么这里要使用MY_THROW宏呢?其实是为了方便的把行号、文件名等加入进来,宏展开的时候是在一行上的,这样也使得行号与出错的行号保持一致,而且让代码更简单。
给出异常类的.cpp文件:
1:#include
2:#include
3:#include
4:
5:#include
6:#include
7:
8:#include"exception_test.h"
9:
10:usingnamespace std;
11:
12: ExceptionBase::ExceptionBase(const std::string& msg) throw()
13: : mMsg(msg),
14: mFile(""),
15: mFunc(""),
16: mLine(-1),
17: mStackTraceSize(0)
18: {}
19:
20: ExceptionBase::~ExceptionBase() throw()
21: {}
22:
23:void ExceptionBase::Init(constchar* file, constchar* func, int line)
24: {
25: mFile = file;
26: mFunc = func;
27: mLine = line;
28: mStackTraceSize = backtrace(mStackTrace, MAX_STACK_TRACE_SIZE);
29: }
30:
31: std::string ExceptionBase::GetClassName() const
32: {
33:return"ExceptionBase";
34: }
35:
36:constchar* ExceptionBase::what() constthrow()
37: {
38:return ToString().c_str();
39: }
40:
41:const std::string& ExceptionBase::ToString() const
42: {
43:if (mWhat.empty())
44: {
45: stringstream sstr("");
46:if (mLine > 0)
47: {
48: sstr \n";
71:char** strings = backtrace_symbols(mStackTrace, 10);
72:if (strings == NULL) // Since this is for debug only thus
73:// non-critical, don't throw an exception.
74:return"\n";
75:
76: std::string result;
77:for (size_t i = 0; i 自己,设计,C++,完善,的,异常,处理,类,我们,的,
长坂坡第一次世界大战刘备虽然救回了自己的儿子,却抛弃了自己的两个女儿
抑郁症为何会反复发作?抑郁症为何控制不了自己的情绪
本身这一观点大致没有问题,但是我们面对抑郁症复发时,也需要考虑到抑郁症复发的其他诱病因素,比如之前一次发病后的治疗残余问题。
简单来说,就是这次的抑郁症复发,可能是上一次发作后治疗不彻底造成的。
而对于抑郁症复发,研究表示:第一次抑郁发作之后,今后有50%-85%的患者会复发,并且随着复发次数增多,复发风险越来越大,每多发作一次,风险大约增加16%。
2、生活事件上的刺激:生活中的负面事件的刺激会促使抑郁症的复发,它可能会让患者处在一个高危的状态中,这些负面事件包括和TA人发生冲突、经济困难、失业、失恋、离婚、失去重要的亲人等。
比如有人的另外一半突然提出要和TA离婚,TA没有任何的思想准备,对TA来说这是一件难过的事情,菜叶说说,突然的刺激有可能会引发TA的抑郁情绪。
3、起病年龄早的需要注意:对于抑郁症患者来说,抛开个别特别因素引发的低龄或者是高龄抑郁症患者,大多数的抑郁症患者的起病年龄大多数都在20到30岁之间。
而在这个发病期间中,如果患者的发病年龄越小,那么之后复发的概率相对也会大一些。
4、患者病前的性格:抑郁症患者往往比一般人要悲观一些,但这并不代表经常性格开朗的人就不会得抑郁症,很多抑郁症患者对自己对世界常常倾向于悲观的看待问题,有这类性格特点的人再次发生抑郁的危险性比较高。
据调查显示,内向的抑郁症患者复发率也远远高于外向型患者。
而这类习惯性往坏处的思考方式,我们称其为具有负性认知观念。
这就好比,我们现如今很多朋友会存在有事没事将手机拿出来瞅一眼的习惯,甚至有时候并没有信息提醒,也会拿出手机刷两下子,这就是习惯。
5、患者的依从性比较差:患者对自己的精神疾病没有正确的认识,,总觉得自己得了抑郁症是“见不得人的病”。
当然还有很多人把抑郁症错误地理解为是“矫情病”、“富贵病”,不能正确对待,治疗必然走入误区。
再加上自身的依从性比较差,并且也不积极地配合专业人士的治疗,或者是直接放弃治疗。
也可能在他们感觉自己的病情有所好转的时候,就会停止服药,但这个时候他们并没有达到完全的康复,抑郁症就很容易复发。
抑郁症为什么控制不了自己的情绪抑郁症是由于脑神经递质紊乱引起的,使人的精神混乱,失眠,而导致情绪的不稳定,思维迟钝。
严重时出现的自杀念头。
建议接受脑神经递质的检查,和采取立体醒脑法治疗。
抑郁症为什么会一会好一会坏目前存在一定的情绪问题,例如情绪不稳定或者情绪低落。
一方面与精神心理因素有关,例如学习压力紧张或者受环境因素的影响。
另一方面可能与个性或者躯体因素有关。
青春期青少年处于心身发育时期,人格发育不够成熟,情绪不稳定。
需要调整心态,增强自信心,加强与人沟通,严重者需要心理治疗或者药物治疗。
抑郁症为什么身体特别难受因为像抑郁症的话,它本身就会对一个神经或者是自我的一个生理状态就会有影响,所以的话它也容易导致一个你精神他们的一个平面和一些记忆力的下降,或者是意识的一个问题所产生所以如果是像鱼医生的话,平时要护理一下自身的一个行为或者是健康