最新消息:点击查看大S的省钱秘笈

关于构造/析构函数与主函数调用顺序的疑惑

编程相关 Slyar 124浏览 0评论

文章作者:姜南(Slyar) 文章来源:Slyar Home (www.slyar.com) 转载请注明,谢谢合作。

这学期开了C++课,讲到构造函数和析构函数的时候我产生了一个疑问,老师说要学了操作系统才能明白,暂时先记录一下,以后回来解决。

很早以前就知道main()是程序执行的入口,一直理解的都是操作系统从main()开始的地方执行程序,但是C++又说析构函数在程序执行之后才被自动调用,我的问题就是程序最后的"return 0"和析构函数谁先执行?还有就是全局实例构造函数的调用顺序又是怎么样的?

为了先得到结论,我用VS2008写了一段程序来实验这个问题。

最后的结果很奇怪,很奇怪...

obj1 Constructor called
Main() start
obj2 Constructor called
Main() end
obj2Destructor called
obj1Destructor called

1、全局实例的构造函数在main()之前被调用

2、析构函数都在main()之后被调用

悲剧了,第1个构造函数和最后2个析构函数居然不是main()来调用,那它们到底是谁调用的?显然在main()执行之前程序进行了一些列操作,至少包括全局变量的生成(因为全局变量是定义在堆上的)和main()参数的传递...暂时无视这个问题,欲知后事如何,请看下回分解...

转载请注明:Slyar Home » 关于构造/析构函数与主函数调用顺序的疑惑

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

网友最新评论 (10)

  1. main的return不为0表示没有成功退出?
    李文轩1年前 (2015-10-30)回复
  2. 全局变量是定义在堆上?似乎不对吧。 我知道cin、cout这些东西的构造最早执行,析构最晚执行。
    李文轩1年前 (2015-10-30)回复
  3. 全局对象是早于main函数执行构造的
    阿木6年前 (2011-05-05)回复
  4. 用反汇编看结果,马上得到你想要的。
    刚子6年前 (2010-09-04)回复
  5. @Jutoy 很明显你完全看不懂……
    Epile7年前 (2010-03-30)回复
  6. @ivan =_=,暂时看不懂,看完汇编估计就能看懂了...
    Slyar7年前 (2010-03-28)回复
  7. @小猪 恩,跟踪过后看到了mainCRTStartup,原来是运行时库...我还得看更多...
    Slyar7年前 (2010-03-28)回复
  8. 随便写一个最简单的C程序demo.c,使用gcc编译成可执行文件demo,然后用objdump -d demo 查看一下这个文件中都有哪些符号(或者函数)。你会发现除了,还有许多,最重要的是一个叫的,它就是C/C++的入口,elf文件的入口都是由_start指明的。 再写个demo.s汇编文件: .global _start #导出符号到符号表 _start: movl $1, %eax #调用号 movl $0, %ebx #返回值 int $0x80 #中断 然后, as demo.s -o demo.o #汇编器as ld demo.o -o demo #链接为可执行文件, ./demo执行,然后echo $?查看返回值就是0 如果将demo.s中的_start换成main,ld将失败,提示找不到符号_start之类的。用ld的参数-e指定入口地址为main就行了,ld -e start -o demo demo.o 也就是说_start是先于main被调用的。C++在这里做了很多事(比如调用构造函数)。总体上就是_start>_init>main>_fini。最好用gdb跟踪调试一下,就明白了。 🙂
    ivan7年前 (2010-03-28)回复
  9. 我纯支持
    Jutoy7年前 (2010-03-28)回复
  10. 操作系统并不是直接调用的main()函数,在一个程序的main 函数实际上是由运行时库里的函数(mainCRTStartup)来调用的,而全局对象的初始化也是由这个函数来实现,初始化全局了才会调用main函数,在main函数的return 0;执行完成之后 运行时库函数又会把全局对象析构,所以才造成了你看到的结果,你可以在main里第一句下个断点,调试到断点时再查看一下函数的调用堆栈,会发现在main之外还有一个函数.
    小猪7年前 (2010-03-28)回复