杂谈之C++中的“错误”处理

作者:i_dovelemon

日期:2016 / 02 / 16

来源:CSDN

主题:C++,Assert,指针,错误处理


在公司工作已经有一段时间了,慢慢的发现了一些以前没有注意过的地方。在大学期间,了解过一段时间的“防御式编程”,所以我在写代码的时候,比较喜欢将代码写的防御性很强(在当初的我看来是这样)。在这样的背景下,接触到了Game Gems的几本书。有一本中的一个章节,专门讲解了在游戏编程中,应该大量使用Assert断言来对游戏中的各种判断进行断言,它的好处是能够及早的将错误暴露出来,使得我们能够比较快速的解决游戏中的bug。

在了解了这样的知识之后,我在自己的代码中就大量的使用了Assert断言来保证程序中的错误及早的暴露出来。这样做了之后的确十分有效。但是我们都知道,Assert仅仅在Debug模式下起作用。在Release版本下,所有的Assert代码就不会被执行了。经常写程序的人都知道,Debug和Release版本在很多时候是不一样的,即使在Debug模式下所有的断言能够正常的通过,到了Release版本下也可能出现各种各样的错误。比如如下的代码在debug模式下正常执行了:


Object* a = new Object()

assert(a != NULL && "Allocate memory failed")

a->Draw();


但是到了Release版本下,可能由于系统内存不够,而出现new操作符失败的情况,那么对于上面的代码就会出现对一个空指针a调用函数的情况。而这种情况在Release版本下会使程序意外中断。对于这种情况,有的网友可能喜欢使用如下的方式来进行编写:


Object* a = new Object()

if (a != NULL)

{

a->Draw()

}


的确,这样的代码是能够避免上面所说的导致程序意外退出的灾难。但是这样的代码,如果在Debug模式下也存在错误,那么错误就不能够及早的暴露,可能会给调试程序带来很大的麻烦。

这里还有一点有争议的地方,那就是对于系统内存分配失败这样的操作,导致程序意外退出,这种情况是应该让程序继续执行,还是就应该让其爆掉,意外退出。其实编写程序都是给别人用的,对于用户来说,他们直线要程序能够运行,如果意外退出,总是会给他们带来不好的感觉。所以,即使失败,程序也应该能够继续执行,而不是意外退出。


所以最终,我使用的方法是结合这两个代码:

Object* a = new Object()

assert(a != NULL && "Allocate memory failed")

if (a != NULL)

{

a->Draw()

}


通过这样的方式,的确能够同时满足在Debug模式下及早暴露错误和Release模式程序继续执行的特性。


但是,一旦项目过大,而这样的判断过多的时候,就会给代码阅读和性能带来一定的负担。所以,我想获取能够定制自己的Assert判断,并且能够指定Assert的等级,不同的Assert等级做不同的事情。

比如对于比较轻微的Assert判断,就让它在Debug模式下作用,而Release模式下不起作用。

稍微重要点的Assert判断,就让它在Release下也能够运行,并且能够实现上面我们实现的那样使用if判断包住的功能

更加重要的Assert判断,依然能够在Release版本下运行,并且能够当这种断言失败的时候,向Log文件输入一些Log,便于开发人员追踪错误

对于严重影响程序的一些Assert判断,在Release能够运行,并且弹出错误提示窗口,准确的告知用户在用户可知的情况下的错误提示。


以上是我想到的关于在C++中进行错误处理的一些观点。同时还有一个不是十分明白的地方,C++有异常处理机制,但是为什么使用的频率远远没有Jave,Python这样的语言高了?我想通过C++的异常处理机制,应该能够设计出更加好的错误处理系统出来。


关于上面的这些观点,希望能够有更多的网友给出自己的看法,各位都有什么样方法来进行错误处理了???

你可能感兴趣的:(C++,杂谈,断言)