关于c++对象全局对象析构的几点记录

Posted on 2009-02-25 20:35 蓝尘 阅读(1556) 评论(2)  编辑 收藏 引用 所属分类: C++
#include<iostream>
using std::cout;
using std::endl;
class CDust{
public:
    CDust()
    {
        cout 
<< " CDust constructor " << endl;
    }

    
~CDust()
    {

        cout 
<< " ~CFoo destructor " << endl;
    }
};


CDust A;

int main()
{
    
return 0;
}
我想类似的代码在网上Google下应该有不少
尝试了下,在vc6.0的情况下,是没有输出 "~CFoo destructor", 但这并不代表 ~CDust() 没有执行.
在~CDust里面设置断点,会发现事实上程序运行时进入了析构函数里  // -_! 表达好牵强
本来想实在跟踪这里开始程序发生了什么调用了什么,发现功底不足,完全不明白,就先打断了
而再在' return 0 ' 语句前面加上断点,会看到这个新加的断点比析构里面的断点先到达,... 
以现在c++的造诣和vc6.0的了解情况来看,头痛了
为什么 return 0 后程序不是正常结束了才去执行 全局对象的析构?

改写下代码
#include<iostream.h>

class CDust{
public:
    CDust()
    {
        cout 
<< " CDust constructor " << endl;
    }

    
~CDust()
    {

        cout 
<< " ~CFoo destructor " << endl;
    }
};


CDust A;

int main()
{

    
return 0;

}

这样用旧版本的头文件实现,控制台输出了意外的两个调用 --- 析构函数输出显示了..

是cout在头文件的实现方式不同?

在dev-c++里面,运行第一代代码
根据断点的设置测试,也是先执行了 main()函数里面的 return 0 才进入全局函数的析构,也能发现析构函数里面的输出被调用了,控制台有明确的显示
这样一来,又不明白了...
在vc6.0里面为什么执行了全局函数的析构却没有所谓的输出?
是因为cmd控制台在'return 0'程序权限收回  // 好像扯到系统的一些混乱的旧记忆了...

网游了一下
找到暂时比较清晰的说法是:
   In C++, the constructor of a global object is executed before the main() function(of course after the STARTUP code), while the destructor
is invoked after the main() function. So in my humble opinion, the main() function is a bridge between the constructor and the destructor.Further more, the constructor and the destructor is the actual manager of the whole program, because they can manage all the
resources of the program(for instance, the constructor allocate memory units and the destructor free them.I'am not sure of this, any comments will be appreciated in advance.).
4)In C++, is it true that the resources obtained during the constructor and the destructor (both belong to a global object)are managed by themselves and have nothing with the main() function.Therfore, I think the main() function is not the king in C++ as it is in C. 
   //感谢提出此说法的朋友
 
  _startup才是用户程序的起点和终点? 的确,调用_exit()函数再断点测试,全局对象的destructor是没有进入的机会   //长见识了

  就此先打断... 再深入今晚就这样完了.
  就此记录下,以后再接触



不小心又接触了...
懒得开新的就集中在这里吧

在main()里面手动调用全局对象的析构, 最后程序都会执行两次析构调用... 在<iostream.h>的cout这种情况下明显,在std::cout下还得靠断点设置才能体现到(vc6的情况)
     这里是一种解析
     {
      Once a destructor is invoked for an object, the object no longer exists; the behavior is undefined if the destructor is invoked for an object whose lifetime has ended. [Example: if the destructor for an automatic object is explicitly invoked, and the block is subsequently left in a manner that would ordinarily invoke implicit destruction of the object, the behavior is undefined
}
     非global static object 也会出现两次调用, 区别只在与一个在main() 退出之前,一个在之后...
(的确,手工调用析构函数的情况很少出现  -_! )
     如果我在析构里面存在 释放内存 这一类实现, 那第二次再次释放不是容易出问题!!!
     以后遇到这种情况得注意检测代码的添加...

Feedback

# re: 关于c++对象全局对象析构的几点记录  回复  更多评论   

2009-02-26 12:05 by 陈梓瀚(vczh)
说不定因为cout被析构了,你的代码就没看到输出了。

# re: 关于c++对象全局对象析构的几点记录  回复  更多评论   

2009-02-27 19:28 by 蓝尘
@陈梓瀚(vczh)
std::cout 被析构, 而且是只在vc6.0下面的 global static object ? 也就是说剩下的就是编译器的实现问题了(网上的说法好像只有std::cout在vc6有这个情况)
等有时间时调试跟踪下...
多谢提醒了

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


Copyright © 蓝尘