| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2426 人关注过本帖
标题:[讨论]关于析构函数的调用顺序
只看楼主 加入收藏
幽园香客
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:231
专家分:142
注 册:2006-2-27
结帖率:50%
收藏
 问题点数:0 回复次数:15 
[讨论]关于析构函数的调用顺序

如题,在调用析构函数时,其顺序和构造函数的顺序完全相反。例如:
class A
{
public:
A(){cout<<"A construction"<<endl;}
~A(){cout<<"A destruction"<<endl;}
};
class B
{
public:
B(){cout<<"B construction"<<endl;}
~B(){cout<<"B destruction"<<endl;}
A a;
};

main()
{
B b;
}
则其结果如下:A construction
B construction
B destruction
A destruction
结果验证了上述结论,可是问题就在后两个。
“析构函数只是在类对象生命结束时,由系统调用”---钱能 《C++程序设计教程》
我就搞不清楚了,为什么B对象结束比A对象还早?明明是在B对象中调用A的对象,B先被析构?一旦B被析构,岂不是B对象的一些资源都被释放掉了(假如有的话)?还有如果从调用机理来说,也是说不通的。哪位兄弟知道,到底为什么?谢谢了

[此贴子已经被作者于2007-3-19 16:27:10编辑过]

搜索更多相关主题的帖子: 函数 顺序 
2007-03-19 16:26
浮0云
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2007-3-19
收藏
得分:0 
我发表一下看法:我觉得B对象先被析构是合理的,假设A对象先被析构,B对象还在运行,用到A对象时,又会调用A对象的构造函数;当B对象先被析构时,A对象自然没有用到的可能了。
2007-03-19 18:16
幽园香客
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:231
专家分:142
注 册:2006-2-27
收藏
得分:0 

问题关键是:A对象是B类中成员,如果把B对象析构了,那么B对象中所拥有的一切资源都将失去。那么A对象怎么能还调用?


做个有用的人!
2007-03-19 18:56
song4
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:38
帖 子:1533
专家分:4
注 册:2006-3-25
收藏
得分:0 
.....
再说一边
构造好比分东西
先长辈,后朋友,最后自己
析构好比干活
先自己,后朋友,最后长辈

嵌入式 ARM 单片机 驱动 RT操作系统 J2ME LINUX  Symbian C C++ 数据结构 JAVA Oracle 设计模式 软件工程 JSP
2007-03-19 19:14
幽园香客
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:231
专家分:142
注 册:2006-2-27
收藏
得分:0 
楼上说的很形象,也很贴切。我翻阅了几本C++方面的书,都是只是提到析构函数的调用顺序,却总是没有讲为什么是这样。知其然,知其所以然!呵呵,或许,过于钻牛角尖了!不过,总还是希望能够得到一个合理的解释。

[此贴子已经被作者于2007-3-19 21:14:15编辑过]



做个有用的人!
2007-03-19 21:12
Arcticanimal
Rank: 3Rank: 3
等 级:论坛游民
威 望:7
帖 子:341
专家分:20
注 册:2007-3-17
收藏
得分:0 

谈谈自己的看法
析构函数代码的执行是有一个过程的,
在这个过程中对象所占有的资源是被逐步释放的,并不是唰的一下全没了,(如果C++的析构函数有代码给我们看这个问题就会很清楚了
当派生类析构函数执行到 清除从基类继承来的对象占有的资源时 便调用基类的析构函数,
基类的析构函数执行完后返回派生类的析构函数继续执行剩余的代码。


try new catch
2007-03-19 21:34
幽园香客
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:231
专家分:142
注 册:2006-2-27
收藏
得分:0 
楼上的,其实如果按照上面你说的情况,我想结果更应该是先调用A对象的析构函数,再调用B的析构函数。因为,如果B中不止一个资源需要释放,当释放A对象所占资源时去调用A的析构函数;然后再调用B的析构了。按照我们通常考虑函数嵌套调用的方法去考虑这个问题时,就会得到和事实相反的结果。

做个有用的人!
2007-03-19 22:07
song4
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:38
帖 子:1533
专家分:4
注 册:2006-3-25
收藏
得分:0 
以下是引用幽园香客在2007-3-19 21:12:38的发言:
楼上说的很形象,也很贴切。我翻阅了几本C++方面的书,都是只是提到析构函数的调用顺序,却总是没有讲为什么是这样。知其然,知其所以然!呵呵,或许,过于钻牛角尖了!不过,总还是希望能够得到一个合理的解释。

很正常
构造顺序我就不说了
至于析构
你可以这么想
如果不销毁自己,而是父类
那么你delete 自身的语句不是有问题么
既然你写的是delete 自身
当然先从自己开始
另外
父类与子类在存储上是包容的关系
子类内部包含父类
先析构自身的成员
然后到了父类那里
//当然,这里父类的空间是子类空间的一部分
//可以想象到覆盖,因为你delete子类,所以实行子类的
//析构,而父类在子类中,所以当析构完成到父类那里调用父类
//至于你会问为什么不县析构父类,然后在析构子类成员呢
//他们都是子类一部分啊
//因为析构是分步的,根据构造顺序,我们可以知道父类是在最里面的
//指针需要一点一点上移动
//当然需要最后了
子类构造函数调用父类的析构函数
至于友类跟这个差不多


嵌入式 ARM 单片机 驱动 RT操作系统 J2ME LINUX  Symbian C C++ 数据结构 JAVA Oracle 设计模式 软件工程 JSP
2007-03-20 08:18
song4
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:38
帖 子:1533
专家分:4
注 册:2006-3-25
收藏
得分:0 
以下是引用Arcticanimal在2007-3-19 21:34:41的发言:

谈谈自己的看法
析构函数代码的执行是有一个过程的,
在这个过程中对象所占有的资源是被逐步释放的,并不是唰的一下全没了,(如果C++的析构函数有代码给我们看这个问题就会很清楚了)//这个有办法实现吧
当派生类析构函数执行到 清除从基类继承来的对象占有的资源时 便调用基类的析构函数,
基类的析构函数执行完后返回派生类的析构函数继续执行剩余的代码。


嵌入式 ARM 单片机 驱动 RT操作系统 J2ME LINUX  Symbian C C++ 数据结构 JAVA Oracle 设计模式 软件工程 JSP
2007-03-20 08:19
Arcticanimal
Rank: 3Rank: 3
等 级:论坛游民
威 望:7
帖 子:341
专家分:20
注 册:2007-3-17
收藏
得分:0 
我是说系统自动生成的析构函数具体清除内存占用的代码,多谢斑竹指点

[此贴子已经被作者于2007-3-20 19:47:09编辑过]



try new catch
2007-03-20 19:06
快速回复:[讨论]关于析构函数的调用顺序
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017007 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved