转自 乾坤一笑 给出程序:#include int main(int argc, char* argv[]) { std::cout << "Hello, world !\n"; return 0; } 修改它,使之产生输出:before main() Hello, world ! after main() 但不要对main()做任何修改。 ---------------------------------------------------------------------------#include struct Foo { Foo() { printf("before main()\n"); } ~Foo() { printf("after main()\n"); } }; Foo smallFoo; int main(int argc, char* argv[]) { std::cout << "Hello, world !\n"; return 0; } 哈哈,就这么就搞定了。这利用了C++的一个特性——一个全局对象在“程序开始时”建立一次,在“程序终止时”销毁一次。(参见《C++程序设计语言(特别版)》10.4.3节 构造和析构) 注意,不要把Foo函数中的printf()换成cout,不然你会哭的!(不信你试试:p) 七猫说,这是因为在smallFoo析构前,中的类已经被析构了。有什么问题问七猫,偶不知道。^_^ 相关文章:jozu 《Run before CRT 》 -------------------------------------------------------------------- 2004-11-14 补充: 今天我做了MWEP,测试了一下,发现在MingW的g++ 3.1.0下,编译这段代码:#include <iostream> using namespace std; struct Foo { Foo() { cout << "before main" << endl;} ~Foo() { cout << "after main" << endl;} }; Foo smallFoo; int main(int argc, char* argv[]) { std::cout << "Hello, world !\n"; return 0; } 结果和上个例子给出的一样,是正确的。莫非是VC6.0编译器实现的有问题? posted on 2004-11-12 08:33 乾坤一笑 阅读(5622) 评论(22) 编辑 收藏 Comments # re: 在main()前后执行代码(C++版本) Bill David 你如果用cout发现什么奇怪现象了?cout肯定在smallFoo之前声明的,所以应该在它之后释放啊? Posted @ 2004-11-12 09:35 # to Bill David : 一笑 如果换成cout就没有"after main()"输出了,你可以试试看,我在VC6.0中试过了。 Posted @ 2004-11-12 11:09 # ^_^, I do not find any problem in the following code on my system Bill David #include <iostream> using namespace std; struct Foo { Foo() { cout << "before main" << endl;} ~Foo() { cout << "after main" << endl;} }; Foo smallFoo; int main(int argc, char* argv[]) { std::cout << "Hello, world !\n"; return 0; } Posted @ 2004-11-13 03:04 # re: 在main()前后执行代码(C++版本) 七猫 程序主入口点其实是 maincrtstartup,这些东西的初始化在这时候就完成了。然后才调用main函数,VC原代码里的。 BTW: to Bill David it depends on complier. C++ standards seems to no guarantee it Posted @ 2004-11-13 03:12 # re: 在main()前后执行代码(C++版本) 七猫 这是全局变量的一个问题,既不能保证他们的构造次序,也不能保证析构次序。不管你哪个在前哪个在后声明。 这个曾经在C++标准委员会讨论过的,但我没有继续关注。 Posted @ 2004-11-13 03:14 # re: 在main()前后执行代码(C++版本) Bill David to 七猫: 对于全局变量的初始化顺序,如果在不同文件中,自然无法保证顺序,但如果在同一文件中,先声明的怎么可能后初始化呢?你的应用程序先#include <iostream>,然后才声明的smallFoo,所以,我认为cout先被声明先被初始化,析构时按与此相反的顺序进行析构. 对于多文件的情况,则肯定用printf比较安全. to 一笑: 我用的是VC6 + sp6(Win2000 sp4) Posted @ 2004-11-15 08:45 # re: 在main()前后执行代码(C++版本) soloist to Bill David: 如果把你所说的那段话中的"声明"换成"定义"就是对的.同一文件中全局对象的初始化顺序与它们的定义顺序一致,而不同文件中定义的全局对象初始化顺序C++标准就不给予保证了。仔细看看<iostream>头文件,你会发现如下代码(VC7.1): extern _CRTIMP2 ostream cout, *_Ptr_cout; 这说明这个头文件只是声明了cout对象,并没有定义它。cout与包含<iostram>的源文件中定义的全局对象仍然分属不同模块,所以它们的初始化顺序不确定。 to 七猫: 不同模块中的全局对象初始化顺序是无法确定的,但是所有全局对象的析构顺序与它们的初始化顺序相反能否确定?C++标准有规定吗? Posted @ 2004-11-20 08:01 # re: 在main()前后执行代码(C++版本) flyer_2001 vc98\crt\src\crt0.c中 #ifdef WPRFLAG __winitenv = _wenviron; mainret = wmain(__argc, __wargv, _wenviron); #else /* WPRFLAG */ __initenv = _environ; mainret = main(__argc, __argv, _environ); #endif /* WPRFLAG */ #endif /* _WINMAIN_ */ exit(mainret); 先执行exit(mainret) 后执行的析够函数 ~Foo() { std::cout << "after main" << endl;} 设置断点,按F10进行调试即可看到 WIN2003 VC6+SP6 Posted @ 2006-04-28 13:06

评论