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

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 【题目】阅读程序,先分析程序的执行结果,在上机时运行程序进行对照,再通过单步执行跟踪程序的运行,达到理解基类、派生类中构造函数、析构函数执行过程的目的。 程序如下: #include <iostream>using namespace std;class Part  //部件类{public:    Part();    Part(int i);    ~

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

程序如下:

#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先定义,而析构函数的执行却在后。
这个结果是由系统自动决定的,程序员需要明白其中的游戏规则。


目录
相关文章
|
1天前
|
数据挖掘 vr&ar C++
让UE自动运行Python脚本:实现与实例解析
本文介绍如何配置Unreal Engine(UE)以自动运行Python脚本,提高开发效率。通过安装Python、配置UE环境及使用第三方插件,实现Python与UE的集成。结合蓝图和C++示例,展示自动化任务处理、关卡生成及数据分析等应用场景。
16 5
|
1月前
|
存储 负载均衡 监控
数据库多实例的深入解析
【10月更文挑战第24天】数据库多实例是一种重要的数据库架构方式,它为数据库的高效运行和灵活管理提供了多种优势。在实际应用中,需要根据具体的业务需求和技术环境,合理选择和配置多实例,以充分发挥其优势,提高数据库系统的性能和可靠性。随着技术的不断发展和进步,数据库多实例技术也将不断完善和创新,为数据库管理带来更多的可能性和便利。
109 57
|
20天前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
50 12
|
18天前
|
存储 网络协议 算法
【C语言】进制转换无难事:二进制、十进制、八进制与十六进制的全解析与实例
进制转换是计算机编程中常见的操作。在C语言中,了解如何在不同进制之间转换数据对于处理和显示数据非常重要。本文将详细介绍如何在二进制、十进制、八进制和十六进制之间进行转换。
28 5
|
26天前
|
存储 机器学习/深度学习 编解码
阿里云服务器计算型c8i实例解析:实例规格性能及使用场景和最新价格参考
计算型c8i实例作为阿里云服务器家族中的重要成员,以其卓越的计算性能、稳定的算力输出、强劲的I/O引擎以及芯片级的安全加固,广泛适用于机器学习推理、数据分析、批量计算、视频编码、游戏服务器前端、高性能科学和工程应用以及Web前端服务器等多种场景。本文将全面介绍阿里云服务器计算型c8i实例,从规格族特性、适用场景、详细规格指标、性能优势、实际应用案例,到最新的活动价格,以供大家参考。
|
2月前
|
XML 数据格式
HTML 实例解析
本文介绍了HTML中常见元素的使用方法,包括`&lt;p&gt;`、`&lt;body&gt;`和`&lt;html&gt;`等。详细解析了这些元素的结构和作用,并强调了正确使用结束标签的重要性。此外,还提到了空元素的使用及大小写标签的规范。
|
3月前
|
数据可视化 Python
Python绘制基频曲线——实例解析与应用探讨
Python绘制基频曲线——实例解析与应用探讨
62 9
|
2月前
|
数据可视化 Python
Python绘制基频曲线——实例解析与应用探讨
Python绘制基频曲线——实例解析与应用探讨
25 0
|
4月前
|
开发者 测试技术 Android开发
Xamarin 开发者的五大常见问题及解决方案:从环境搭建到性能优化,全面解析高效跨平台应用开发的技巧与代码实例
【8月更文挑战第31天】Xamarin 开发者常遇问题及解决方案覆盖环境搭建至应用发布全流程,助新手克服技术难关。首先需正确安装配置 Visual Studio 及 Xamarin 支持,设置 iOS/Android 测试环境。利用 Xamarin.Forms 和 XAML 实现高效跨平台开发,共享 UI 和业务逻辑代码。针对性能优化,采取减少 UI 更新、缓存计算结果等措施,复杂问题则借助 Xamarin Profiler 分析。
53 0
|
4月前
|
数据采集 弹性计算 供应链
阿里云服务器付费模式:按量付费、包年包月和抢占式实例全解析
阿里云服务器提供包年包月、按量付费与抢占式实例三种付费模式。包年包月为预付费,适合长期稳定使用,价格更优惠并支持备案。按量付费则为后付费模式,按小时结算,适合短期或访问量波动大的场景,但不支持备案。抢占式实例基于按量付费,价格更低(最多节省90%),适用于无状态应用,如临时测试或可弹性伸缩的Web服务,但存在被系统释放的风险,同样不支持备案。根据具体需求选择合适的付费模式能够有效降低成本并提高效率。
210 0

推荐镜像

更多
下一篇
DataWorks