掌握CB的调试艺术[VC/C++编程]
本文“掌握CB的调试艺术[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
程序的bugs越少,终究用户对这个程序的评价越高.而开辟人员事前对bugs的处理越多,终究用户能供应的关于bugs的信息就越多,也越精确,这样,开辟人员在接到终究用户反映之后,就可以够快速找到呈现bugs的那部份代码,并以最快速度公布程序的进级包.
在这份教程中,我们从最基本的部份开始,渐渐介绍很多在调试程序时“应当做”或“不该该做”的原则.正如你将看到的,这份教程中所指的“调试”这个词所包含的意思很多,而不只是如大部份人所想到的--操纵IDE集成的调试器的“调试”.我但愿读过这份教程之后,读者可以在思绪上有所收获.
写易读的代码
第一点,大约也是最重要的一点,就是写干净易读的代码.易读的代码是很有代价的.请想象一下,假如随便扫视一眼代码或注释,就可以立即知道这段代码的的作用,以及在写代码的时刻为什么要这样写,当时的思绪是什么,那么便可以节俭大量时间.这样的代码,在写的时刻大概会稍稍慢一些,不过,当你调试程序时,就不会花上几个小时来探求bugs,相反,你可以快速,简单的完成除错工作.这时,你就会认为多花一些时间使程序易读是很值得的.
所以,我举荐你在写程序的时刻,应当养成自己的气势,或是读一读Scott的关于代码气势的文章.
利用Exceptions和Exception的处理办法
我们教程的下一步,仍旧是以代码为底子的.因为除去一些少数的情形,开辟人员不大概老是依靠于集成的调试工具.所以,学会用别的的办法来找到烦人的bugs是很重要的.一些重要的、处理的错误大概会在窗体之外发生.在C++尺度拟定出来之前的乌黑日子里,在程序里面发动程生错误的信号,普通是通过返回错误代码完成的(目前这种办法仍旧利用于OLE技术和一些Winapi函数),这样的处理办法很简单就会被忽视.(比方说,你常常查抄winapi函数的返回值吗?)所以,呈现问题的大概性并不小.由于以上的缘由,我们需求一个这样的机制,它能让我们不能忽视这些错误,并且,这个机制应当能被我们掌握和自定义的.在这样的需求下,非常处理机制呈现了.需求一个特别的错误范例吗?简单,定义一个新的非常范例就行了(和定义一个类的办法差不多),然后抛出(throw)它.下面这个例子阐明了这一历程.
例1:
//----------------------------------------------------------------
class MyException
{
public:
AnsiString iMessage;
MyException(AnsiString Message) { iMessage=Message;}
};
throw new MyException(“Test Exception Message”);
//---------------------------------------------------------------
就是它!(不是非常好,下面我们会持续完善它).简单高效,并且便于自定义.大概你目前会问:“我可以使抛出非常了,但是,怎么掌握它们呢?我的意思是,我想在代码的最前面解除非常.”C++Builder为我们中定义了try {} catch (…) {}机制.这和我们方才定义的非常机制的构造很类似.这个机制完好可以按照需求自定义.要利用非常处理了,只要把要履行的代码放到try块里面,为了让程序知道呈现非常后应当做什么,还需求定义一个catch()或是__finally块.Catch()语句里面可以指定一个要捕捉的范例或是变量(比方例1,就是catch(MyException &E){ /* 非常处理代码/}这个机制很强盛,乃至可以用它来捕捉树构造或是担当类的非常,假如捕捉了基类的非常,它就可以捕捉到担当这个基类的全部的类的非常.比方,在VCL中,全部的非常都是担当于Exception类.所以,catch(Exception& E)可以捕捉到除了EsocketError的全部VCL非常.(这点请分外注意,今后还将持续谈论.)为了让这个机制更强盛,C++Builder中还定义了catch(…)语句.(没错,就是三个点)利用这条语句可以捕捉到全部的非常.还有更多的功效吗?当然,你可以增添更多的catch()语句,可以向利用if…else if…语句那样利用它.注意,在一系列的catch()语句中,错误不会被反复的捕捉,也就是说,假如前面的catch()语句捕捉到了错误,背面的catch()语句将不会捕捉这条错误.
例2:
//----------------------
try
{
// 正常代码
}
catch(EDBEngineError &E)
{
// 处理数据库引擎错误
}
catch(EExternalError &E)
{
// 处理窗口类的错误
}
catch(Exception &E)
{
// 处理全部的VCL错误
}
//----------------------
请看例2,它的代码运行流程是这样的:“错误是EDBEngineError吗?是->处理它.不是->运行下一个catch语句”“错误是EExternalError吗?是-〉处理它.不是-〉运行下一个catch语句”等等.
这个机制还有更多的功效.假如你想处理非常,但是不想在处理的位置终止,那么可以重新抛出非常.这时,程序将持续探求下一个catch()语句来处理这个非常.这个办法和“throw”差不多.这样,你处理过的非常会再次被抛出,持续探求下一个catch语句来处理它.
最后一个要说的是__finally(这不是尺度的用法,是Borland增添的一个好办法),在__finally{}程序块中代码,无论能否发生非常城市被履行.这是一个清理程序中利用new分配的本地变量,设置用作旗标的变量值为正常的好位置.(比方,把一个等候状况的光标图标设置为正常光标.)
就是这些了.有时间的话,请看看C++Builder帮忙文件中的Exception类以及担当Exception的类.这些将关于理解本节所说的内容有很大帮忙.
利用记录机制
你不大概老是用调试器来调试代码,在某些情形下,大概无法利用内部集成的调试器,这时刻,你就不得不依靠其他手段调试程序了.(比方:Windows NT服务程序,ISAPI/CGI程序,及时利用程序等等).这时刻,有经验的程序员大概会借助陈腐的调试办法,比方,利用一些分类的记录机制来肯定程序实际运行的历程.我们很幸运,目前有一系列的办法可以简单的完成这样的工作.下面将介绍3种我最喜好的办法.
第一个:OutputDebugString.(WinAPI: VOID OutputDebugString(LPCTSTR lpOutputString);)很幸运,微软完好的实现了调试子系统.它包含的一些特点大概让你想把自己的记录系统抛弃.利用程序在调试器进程中运行时OutputDebugString将用C字符串把调试器输出的信息打印出来.假如程序没有在调试器进程中运行,它将忽视这些调用.它会很好的在客户的机械上运行,不会弹出信息窗口.假如在公布给客户的时刻,忘掉去掉这些代码程序仅仅会变慢一点,不会有别的不良后果.
第二个办法:利用了Gexperts,通过 dbugint.pas接口举行调试.它是个可以称之为巨大的程序,你可以把它分发给客户.和OutputDebugString一样,假如客户没有这个程序,它就根本什么也不作.(它会自动检测机械上能否安装了客户端).要利用dbugintf,它很简单被加入到你的工程中,加入#include "dbugintf.HPp"(要把它加入工程,然后会编译它的pascal文件).然后,你便可以直接利用SendDebug(要送到记录文件的字符串); 大概,你需求它更机警一些,可以利用SendDebugEx(它给TMsgDlgType增添了一个新的消息范例)SendMethodEnter, SendMethodExit, SendSeparator等等(用法都差不多).假如你打算给终究用户分发客户端 (Gdebug.exe),不要忘掉include所需求的程序包.Gexperts可以在http://www.gexperts.org 得到,它是免费的.
第三个,大约是最艰苦的办法,就是利用你自己的记录掌握.这个办法大概不是你想象的这么简单.你大概首先会想到“在窗体上扔一个RichEdit,把它设置为只读的,然后往里面写记录”是这样吧?理论上不错,但是,实施起来…首先,利用RichEdit控件来做记录,会大大降低利用程序的速度,还会在内存中造成碎片,乃至丧失内存.普通,在运行10分钟左右之后,会使整个计算机的速度变慢!(这样做简直是在犯罪!)所以,假如你但愿在自己的记录中可以利用彩色和图标,那么最好自己成立一个组件.假如没有这么高的要求,那么有一个简单有效的办法,就是利用ListBox控件作记录,把ListBox的Style属性设置为lbOwnerDrawFixed,这样句柄将会自绘.(Gexperts的掌握台就是用这样的办法制作的).
以上是“掌握CB的调试艺术[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |
- ·上一篇文章:<b>C++ Builder编写文本编辑器</b>
- ·下一篇文章:BCB6号令行工具简介
- ·中查找“掌握CB的调试艺术”更多相关内容
- ·中查找“掌握CB的调试艺术”更多相关内容