让atexit()对付那些一闪而过的控制台程序

用过各种 C/C++ 的 IDE,有些真的让人很蛋疼。比如说用 Dev-C++(记不清是不是它了,好像VS也有这情况),编写控制台程序,调试运行,程序一执行完毕控制台窗口就闪没了,强烈考验我们的眼里。通常呢,我们会在后面加上一条具有阻塞功能的语句比如:

// 版本 1
// #include <conio.h>
getch();


  // 版本 4
// #include <stdlib.h>
system("pause");
// 版本 3
// 在 C++ 中也可以是
// #include <iostream>
char chNothing;
std::cin
>> chNothing;

 
// 版本 2
// #include <stdio.h>
getchar();

上面这些版本都是我们常用,一般把它们放在 main 函数最后面,return 语句的前面。结果就是程序执行到这里发生阻塞,等待我们输入一个字符或者按任意键后程序才结束。在此之前,我们就有足够的时间来查看程序执行结果了。不过这些用法是有缺点:

1) 对于版本 1,由于 conio.h 并不是标准头文件,并不是所有的 IDE 都会附带它,貌似 Dev-C++ 上没带。

1) 对于版本 1、2、3,如果在程序中执行过程中不小心输入过多的字符,那么我们的阻塞防线很容易就被突破;

2) 对于定义在 main 函数中的对象,正常情况下,它们的析构函数是在 main 函数返回后才被调用的。而这些阻塞语句都是在 main 函数中被调用,所以我们很难观察到析构函数的执行结果,甚至可能认为析构函数没有被调用。

解决上述问题的一个方法就是在 main 函数执行完毕后再执行一段阻塞代码,这就需要用到 atexit 函数了。我们将使用 atexit 来注册一个在 main 结束之后才调用的函数,并在这个函数里面调用版本 4。

//
// 让 atexit 函数对付那些一闪而过的控制台程序.
//
// 我觉得你最好找个执行控制台程序时会一闪而过的 IDE 来测试下面的代码.
// 你需要做的是把最后面的 atexit 函数调用语句注释掉来看看和原来有什么不同之处.
// 你可以在 Dev-C++上试试,虽然我好久没有用过它了. 也可在 VS 上试试,
// 我刚用 VS2008 试过。C-Free 不会一闪而过,如果你用它的话.
// 如果你有用 CodeBlocks 的话也试试看. 好吧,你正在当我的小白鼠.
//


#include
<cstdlib>
#include
<iostream>
 
//
// 在 main 函数执行完毕后被调用的函数.
//
void calledAfterMain(void)
{
   
// 我们的版本 4.
    system("pause");
}
 
//
// 用来测试的类.

// 我们将在 main 函数中实例化一个对象.
//
class Clx
{
public:
Clx(
void)
{ std::cout
<< "构造函数" << std::endl; }

~Clx(void)
{ std::cout
<< "析构函数" << std::endl; }
};
int main(void)
{
//
// 测试用的对象.
// 注意在控制台中观察它的输出.
//
Clx objTest;

//
// 其他的语句...

    //
 

    //
    // 请在下次执行的时候把 atexit 函数调用语句注释掉,看看有什么不同.
    //
    atexit(calledAfterMain);


   
return EXIT_SUCCESS;
}

 哈,atexit 函数的这种用法不错吧!

posted @ 2011-05-26 15:03  Atypiape2  阅读(1369)  评论(4编辑  收藏  举报