5 使用句柄和指针
初始化一个指针时,要么让其指向一个有效的内存地址,要么设为0(空指针),避免指针指向无效地址。回收指针所指对象时要重新初始化这个指针,并且在指针被释放前为空时就对其进行处理。对句柄的处理跟指针一样。
6 用引用而不是指针做参数
用指针做函数的参数可传递一个空指针,很灵活,但也很容易忘了对指针进行初始化。而引用是对象的别名,它必须和有效的对象相关联,不存在空的和没有初始化的引用。当在函数中收到一个引用参数时,可以肯定这是一个有效的对象。程序用引用做参数比用指针做参数更为健壮。
7 强制类型转换(cast)
进行数据类型的强制类型转换时,将会调用相应的构造函数或转换函数来创建一个新类型的临时对象。对指针的正确类型转换可消除一个编译错误,但并没改变指针。强制类型转换破坏了编译器进行类型检查的功能,而这正是编译器查找错误的最有效的机制。为了保证安全性,每一个强制类型转换都需要手工进行类型检查。为尽量避免强制类型转换,你可以:避免使用多态数据类型;使用更加广泛的基类;提供特殊的存取函数;让编译器隐式处理类型转换等措施。
8 使用构造函数和析构函数
构造函数需要分配内存,创建资源或者打开文件,这些运算并不总是成功。构造函数没有返回值,没有直接显示错误的方法。一个常见的方法(在很多MFC类中使用)是把对象创建分为两步:第一步,让构造函数以一种不会出错的方式初始化对象;第二步,让某些初始化函数(如Init或Open)完成工作,这一步可能出错。另一种方法是在构造函数中使用异常:第一步,以不会出错的方式初始化对象;第二步,用可能在try段内出错的代码初始化对象;第三步,在catch代码里面处理异常。如果出现异常,就会在构造函数里清除分配的资源,并且再次抛出异常。
异常处理的一个关键细节就是在栈展开的过程中抛出的异常会终止整个应用程序。在处理异常时经常要调用析构函数,因此析构函数很容易出错,一定要保证析构函数的异常在析构函数中得到处理。要保证基类的析构函数是虚函数。这样,就算对象是一个指向基类的指针,也会调用派生类的析构函数。否则,就会引起资源泄漏(resource leak)。
在VC程序中使用调试语句
为了更好地对程序调试,可以使用如下方法:使用断言、使用跟踪语句、使用异常和返回值。
一、断言
1、基本概念
断言是一种让错误在运行时候自我暴露的简单有效实用的技术。它们帮助你较早较轻易地发现错误,使得整个调试过程效率更高。
断言是布尔调试语句,用来检测在程序正常运行的时候某一个条件的值是否总为真,它能让错误在运行时刻暴露在程序员面前。使用断言的最大好处在于,能在更解决错误的发源地的地方发现错误。断言具有以下特征:
.断言是用来发现运行时刻错误的,发现的错误是关于程序实现方面的。
.断言中的布尔表达式显示的是某个对象或者状态的有效性而不是正确性。
.断言在条件编译后只存在于调试版本中,而不是发布版本里。
.断言不能包含程序代码。
.断言是为了给程序员而不是用户提供信息。
使用断言最根本的好处是自动发现许多运行时产生的错误,但断言不能发现所有错误。断言检查的是程序的有效性而不是正确性,可通过断言把错误限制在一个有限的范围内。当断言为假,激活调试器显示出错代码时,可用Call Stack命令,通过检查栈里的调用上下文、少量相关参数的值以及输出窗口中Debug表的内容,通常能检查出导致断言失败的原因。_ASSERTE宏(属于C运行时间库)还能在断言失败时显示出失效断言。下面我们讨论一下MFC库中的断言。
2、MFC库中的断言
(1) ASSERT(布尔表达式)
用MFC时最好选择ASSERT宏,它的优点是即使出现了WM_QUIT消息也能显示断言失效消息框。
(2) VERIFY(布尔表达式)
VERIFY宏中的布尔表达式在发布版本中被保留下来。VERIFY宏简化了对函数返回值的检查,一般用来检查Windows API的返回值。由于VERIFY宏里的布尔表达式在发布版本里保留了下来,因此最好尽量不要使用这个宏以实现程序代码和调试代码的完全分离。
(3 )ASSERT_VALID(指向CObject派生类对象的指针)
ASSERT_VALID宏通过调用重载的AssertValid函数来确定指向CObject派生类对象的指针是否有效。无论你什么时候从CObject派生类中得到一个对象,在对这个对象做任何操作之前都应该调用ASSERT_VALID宏。
(4) ASSERT_KINDOF(类名, 指向CObject派生类对象的指针)
这个宏用来验证指向CObject派生类对象的指针是否从某个特殊类中派生,在调用它之前先调用ASSERT_VALID宏。只有在很特殊的场合下才用得到,如检测编译器可能错过的对象类型问题。
此外,还有两个没有正式文件的ASSERT宏的变种:ASSERT_POINTER(指针,指针类型),ASSERT_NULL_OR_POINTER(指针,指针类型)。  
说明:本教程来源互联网或网友上传或出版商,仅为学习研究或媒体推广,wanshiok.com不保证资料的完整性。
2/2 首页 上一页 1 2 |