| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2424 人关注过本帖
标题:[讨论]关于析构函数的调用顺序
只看楼主 加入收藏
Arcticanimal
Rank: 3Rank: 3
等 级:论坛游民
威 望:7
帖 子:341
专家分:20
注 册:2007-3-17
收藏
得分:0 
以下是引用幽园香客在2007-3-19 22:07:36的发言:
楼上的,其实如果按照上面你说的情况,我想结果更应该是先调用A对象的析构函数,再调用B的析构函数//此句不妥,怎么会是这样呢因为,如果B中不止一个资源需要释放,当释放A对象所占资源时去调用A的析构函数;然后再调用B的析构了//此处不应该是“再调用”,只是返回B的析构函数继续执行。按照我们通常考虑函数嵌套调用的方法去考虑这个问题时,就会得到和事实相反的结果。

#include<iostream.h>
class baseone
{
public:
baseone(){cout<<"baseone() called!\n";}
~baseone(){cout<<"~baseone() called!\n";}
};
class basetwo
{
public:
basetwo(){cout<<"basetwo() called!\n";}
~basetwo(){cout<<"~basetwo() called!\n";}
};
class derive
{
public:
derive(){cout<<"derive() called!\n";}
~derive(){cout<<"~derive() called!\n";one.~baseone();two.~basetwo();} //虽然显式调用基类析构函数,系统还是会再一次调用基类析构函数
baseone one;/////////
basetwo two;//改变 one 与two 的声明先后会导致系统自动调用 baseone 与 basetwo的析构函数顺序不同
};
void main()
{
derive der;
}
最终~basetwo()与~baseone()都调用了两次


try new catch
2007-03-20 19:44
幽园香客
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:231
专家分:142
注 册:2006-2-27
收藏
得分:0 
谢谢6楼和song4!经过这两天的讨论,我对析构函数又有了更进一步认识。

做个有用的人!
2007-03-20 20:28
江南孤峰
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2006-11-8
收藏
得分:0 

创建实例时,程序首先初始化对象的数据成员: A construction
调用构造函数: B construction
C++在释放对象前调用析构函数:B destruction
删除对象的一切数据: A destruction
通常对数据成员的处理(初始化或者删除)是在构造和析构函数里执行
但A是一个类成员,在B的构造函数调用前被自动调用,B在没有调用析构
函数前,B的数据成员都是有效的,B调用析构函数后 A的生命周期也随之
结束,因此A自动调用其自身的析构函数.

2007-03-21 09:57
幽园香客
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:231
专家分:142
注 册:2006-2-27
收藏
得分:0 
这两天,又仔细琢磨了下。觉得问题关键应该是和栈有关。一个最简单的例子:
class CA
{ public:
CA(){cout<<"CA construction"<<endl;}
~CA(){cout<<"CA destruction"<<endl;}
};
class CB
{ public:
CB(){cout<<"CB construction"<<endl;}
~CB(){cout<<"CB destruction"<<endl;}
};
void main()
{
CA a;
CB b;
}
结果还是:CA construction
CB construction
CB destrutcion
CA destruction
在这里没有包含或者被包含的关系,或者是继承与被继承的关系,可是输出结果仍旧是先前我们说的那样。可见,析构函数的处理过程和栈有关系--先进后出。至于在一个类中声明另外类的对象,或者一个类继承另外一个类,都只不过是析构函数的一个特殊应用而已。我想最终还是需要从析构函数的实现原理上去考虑这个问题。呵呵


做个有用的人!
2007-03-24 22:27
song4
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:38
帖 子:1533
专家分:4
注 册:2006-3-25
收藏
得分:0 
呵呵
我们说的也是栈的原理啊
但是我说的是原理
为什么呢
因为这样做最安全
怎么样做??
按构造相反的顺序析构
为什么这样最安全呢???
因为在不知道基类里面是否有与子类有关的东西
的情况下,只有与其相反的顺序返回才不会
涉及到析构基类影响子类的情况

嵌入式 ARM 单片机 驱动 RT操作系统 J2ME LINUX  Symbian C C++ 数据结构 JAVA Oracle 设计模式 软件工程 JSP
2007-03-24 22:41
幽园香客
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:231
专家分:142
注 册:2006-2-27
收藏
得分:0 
晕,刚才写的那么多东西,提交时出现错误,文字全没了!
谢谢楼上的几位,经过几天来的讨论,我想是不是这样认识这个问题:首先,需要澄清一个错误的认识:调用了子类的析构函数,就释放了占用的所用资源。根据“类与类之间,你做你的,我做我的,以接口作沟通。即使基类与子类也不例外”(引自:钱能 《C++程序设计教程》)的原则,子类的析构函数只是释放自己做申请的那部分资源;基类的资源的释放还是需要调用基类的析构函数。这样以来,基类和子类的的析构函数是各司其职。
总体来说:构造函数是一个入栈过程,而析构函数则是一个出栈的过程。

做个有用的人!
2007-03-25 11:28
快速回复:[讨论]关于析构函数的调用顺序
数据加载中...
 
   



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

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