第10周-任务0-构造和析构函数的执行过程实例解析

【题目】阅读程序,先分析程序的执行结果,在上机时运行程序进行对照,再通过单步执行跟踪程序的运行,达到理解基类、派生类中构造函数、析构函数执行过程的目的。

程序如下:

#include <iostream>
using namespace std;
class Part  //部件类
{
public:
    Part();
    Part(int i);
    ~Part();
 private:
    int val;
};

class Whole: public Part
{
public:
    Whole();
    Whole(int,int,int,int);
    ~Whole();
private:
    Part one;
    Part two;
    int data;
};

Part::Part()
{
    val=0;
    cout<<"The default constructor of part was called "<<val<<endl;
}

Part::Part(int i)
{
    val=i;
    cout<<"The constructor of part was called "<<val<<endl;
}

Part::~Part()
{  
    cout<<"The destructor of part was called "<<val<<endl;
}

Whole::Whole()
{
    data=0;
    cout<<"The default constructor of whole was called "<<data<<endl;
}

Whole::Whole(int p, int i,int j,int k):Part(p),two(i),one(j),data(k)
{
   cout<<"The constructor of whole was called "<<data<<endl;
}

Whole::~Whole()
{  
    cout<<"The destructor of whole was called "<<data<<endl;
}

void f()
{
    Whole w1;
    Whole w2(1,2,3,4);
}

int main()
{
    f();
    system("pause");
    return 0;
}

运行结果及解释:

运行结果对运行结果的说明
The default constructor of part was called 0
The default constructor of part was called 0
The default constructor of part was called 0
The default constructor of whole was called 0
程序中第60行定义对象w1时,执行构造函数的结果。
对于基类part、派生类中的part对象成员执行的都是默认构造函数;
最后执行派生类whole的默认构造函数的函数体中的语句。
The constructor of part was called 1
The constructor of part was called 3
The constructor of part was called 2
The constructor of whole was called 4
程序中第61行定义对象w2时,执行构造函数的结果。
调用构造函数的过程也是先基类、再派生类中的对象成员,最后执行派生类构造函数的函数体。
此处执行的均是带参数的构造函数。
注意到在创建对象w2(1,2,3,4)时,第48行函数调用的实参为:Part(1),two(2),one(3),data(4)。
可能让人意外的是,给出的数字是1 3 2 4,而不是1 2 3 4。
这告诉我们,w2中对象成员one的构造函数one(3)执行在前,对象成员two的构造函数two(2)执行在后。
对象成员的构造顺序依其在对象中定义 的顺序(见第20和21行),而不是构造函数中的书写顺序。
为什么?因为在一个whole对象中,各数据成员是顺序存储的,分配空间,one在前,two在后。
C++是人工语言。大多数问题是有依据的,多想想有好处,但初学时常想不到。
所以,一旦有想不通的,将观察得到的现象有大脑中留有映像,随着学习的深入就明白了。
The destructor of whole was called 4
The destructor of part was called 2
The destructor of part was called 3
The destructor of part was called 1
退出f()函数的调用时,结束局部对象w2的生命周期,执行析构函数。
要调用的析构函数的顺序正好与前构造函数的顺序相反:先构造的后析构,后构造的先析构。
The destructor of whole was called 0
The destructor of part was called 0
The destructor of part was called 0
The destructor of part was called 0
退出f()函数的调用时,结束局部对象w1的生命周期,执行析构函数。
w1比w2先定义,而析构函数的执行却在后。
这个结果是由系统自动决定的,程序员需要明白其中的游戏规则。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迂者-贺利坚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值