分享
 
 
 

将程序错误消灭在萌芽中

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

--------------------------------------------------------------------------------

这篇文章贡献自Alex Rest, 翻译: bugfree/CSDN

平台: VC6, VC7, Windows 9x/NT/2000/XP

--------------------------------------------------------------------------------

我同许多学生接触很多, 很好的了解他们的错误. 而且, 我也很了解我的错误. 有一种能使你的程序可信度更高. 它就是应用assertiong宏的陷阱(trap)技术. 下面描述了通常的C++技术和VC++/MFC特殊功能.

1. 为什么必须将指针初始化为 NULL

如果你有

class A{

public:

A();

~A();

//some declarations.

private:

SomeType* m_pPointer;

//some declarations.

};

A::~A(){

delete m_pPointer;

}

如果你在构造函数之外给指针赋值, 你必须总是将它设为NULL. 例如:

A::A():m_pPointer(NULL){}

—为什么?

—因为:

1). 如果你的程序执行的逻辑不为指针创建对象, delete操作将无错的执行(根据C++语言标准). 如果你忘了初始化bypass pointer, 它将有一个随机值, 对这个地址的删除将是你的程序崩溃.

2). 通过用断点和追踪, 你能够容易的找到没有初始化的指针.

3). 你可以用 "if" 操作来测试一个有效地指针, 如:

if(m_pPointer){

m_pPointer->DoSomething();

}

else{

AfxMessageBox("Unexpected error #1234. Send me letter

please to aaa@bbb.com");

}

可能你的程序不能正确工作, 但是在这里它不会崩溃. 这是非常重要的. 想象你已经输入了两个小时文本并没有存盘. 你更希望文本编辑器崩溃呢还是给出一些警告?

4).你可以用ASSERT宏设置调试陷阱(debug trap)

2. 为调试设的陷阱(Traps)

插入断点是一个好技术, 但是如果问题出在长的循环内部那就不是高效的了. 例如, 在10,000次循环之后,一些条件变的有问题了. 为了抓住这样的问题, VC++/MFC 程序员应用 ASSERT 宏. ANSI宏也经常被应用.用哪个不是问题, 在下面的例子中我用了 MFC ASSERT 宏.

—它怎样被用?

—这样:

ASSERT(condition);

例子:

ASSERT(nWaterTemperature > 0 &&

nWaterTemperature < 100); // break if wrong value

ASSERT(pSomePointer); // break if null pointer

ASSERT(0); // break if here

—它怎样工作?

—这样:

断言(assertion)用带断言信息(程序, 模块, assertion行)的对话框执行. 对话框有3个按钮: "Break", "Repeat" ("Debug"), and "Continue" ("Ignore"). "Break" 结束程序, "Continue" 忽略断言, 最有用的是"Repeat"按钮. 按下它在断言的地方打开源代码编辑器. 在这里你可以测试所有的变量值并明白哪里出了问题.

—它怎样用?

—多数这样用:

为了控制传进的指针:

void SomeFun(SomeType* pPointer)

{

ASSERT(pPointer);

//some instructions.

}

你可以在"switch" 和 "if"操作中捕获奇怪的值

例如:

switch(nRGBColors){

case nRed: {//some instructions.} break;

case nGreen: {//some instructions.} break;

case nBlue: {//some instructions.} break;

default: ASSERT(0); // we should have never come here!

}

if(nWaterTemp >=0 && nWaterTemp < 50){

//some instructions.

}

else if(nWaterTemp >= 50 && nWaterTemp <= 100){

//some instructions.

}

else{

ASSERT(0); // we should have never come here!

}

对值的断言:

ASSERT(nSomeValue >= MinValue and nSomeValue <= MaxValue);

ASSERT(nOtherValue != 0);

等.

Always use this technique and you will be greatly surprised how often such traps will work!

总是应用这个技术, 你将被how often这些陷阱将工作 大大震惊.

3. 可爱的 ASSERT 错误

ASSERT( m_MyWnd.Create() );

呕! 这是一个可怕的错误! 程序在调试版中正常工作, 在发行版中不工作. 记住: 这是一个在发行版中将被移除的宏. 以这种方法你的窗口将永远不会被创建. 如果你用 MFC, 这样做:

VERIFY( m_MyWnd.Create() );

它在调试版中像ASSERT一样并且在发行版中执行m_MyWnd.Create()

4. 对象验证及MFC宏ASSERT_VALID

利用类的verify成员是众所周知的验证对象的技术. 如果你有明确的对象的验证条件, 你可以创建和利用verify类成员.

例如:

class Time

{

public:

void Set(int h, int m);

bool Verify(){return m_h>=0 && m_h<24 and m_m>=0 && m_m<60; }

//some instructions.

};

void Time::Set(int h, int m)

{

m_h = h;

m_m = m;

ASSERT(Verify());

}

大多数的MFC类是CObject的子类. 它有用来验证用的AssertValid虚函数 如果一个类实现了这个函数, 他被ASSERT_VALID宏调用. 例如:

ASSERT_VALID(pView);

它检查某个CViewWnd对象的指针. 如果对象无效(空指针或错的窗口句柄), 断言将被执行.

5. MFC TRACE 宏

没有TRACE宏描述的MFC宏的附录将是不调和的. 在主控台模式下用流输出变量的值是没有问题的. 从另一方面来讲, Windows下编程追踪变量并不是一个琐碎的任务.实际上, 当我们追踪某事时许多窗口可以被打开和关闭. 没有必要把追踪输出写到许多窗口上. 一个窗口足够了. 因为这个目的, VC++ IDE应用了"输出"窗口(View-Output menu point). 为了调试输出, 你可以利用TRACE操作符, 它同printf stdio函数具有相同的格式.

例如:

TRACE("\nThis is a trace of int variable %d.", nSomeInt);

TRACE("\nFunction OnInitialUpdate is starting.");

链接:

我的其它文章, demo project, 和许多有趣的C++链接可以在这里找到:

http://www.brigsoft.com/edu

我的软件在这里:

http://www.brigsoft.com.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有