C++构造函数和析构函数的调用顺序

        一般情况下,调用析构函数的次序正好与调用构造函数的次序相反,也就是最先被调用的构造函数,其对应的析构函数最后被调用,而最后被调用的构造函数,其对应的析构函数最先被调用。

        当然对象的构造函数和析构函数调用时机和它的生命周期是密不可分的。 下面归纳一下什么时候调用构造函数和析构函数。
        (1)全局对象(生命周期:程序运行时创建,程序结束时销毁)的构造函数在所有函数(包括main函数)执行之前调用。但如果一个程序中有多个文件,而不同的文件中都定义了全局对象,则这些对象的构造函数的执行顺序是不确定的。当main函数执行完毕或调用exit函数时(此时程序终止),调用其析构函数。
        (2)局部对象(在函数内定义的对象,其生命周期是进入该函数创建,函数退出结束)在进入该函数建立对象时调用其构造函数。如果函数被多次调用,则在每次建立对象时都要调用构造函数。在函数调用结束时调用析构函数。
        (3)如果在函数中定义了静态(static)局部对象(生命周期是第一次进入该函数创建,程序退出时销毁),则只在程序第一次调用此函数建立对象时调用一次构造函数,在调用结束时对象并不被释放,因此也不调用析构函数,只在main函数结束或调用exit函数结束程序时,才调用析构函数。
        (4)动态创建的对象,是调用new关键字创建函数时调用构造函数,调用delete函数销毁对象时调用析构函数。

1.全局变量

例如:构造函数与析构函数执行顺序。


//1.全局对象
class Time  //时间类
{
private:
    int hour;
    int minute;
    int second;
public:
    Time(int h, int m, int s); //构造函数
    ~Time();//析构函数
};
Time::Time(int h, int m, int s) //定义构造函数
{
    hour = h;
    minute = m;
    second = s;
    cout << "时间 构造函数:" << hour << ":" << minute << ":" << second << endl;
}
Time::~Time()//定义析构函数
{
    cout << "时间 析构函数: " << hour << ":" << minute << ":" << second << endl;
}

Time g_a = {8,0,0};
Time g_b = {9,0,0};
static Time g_c = {10,10,10};
static Time g_d = {11,11,11};

int main()
{
    cout << "进入main()" << endl;

    cout << "退出main()" << endl;
    return 0;
}

2.局部变量

对局部对象和局部静态对象的测试如下:

//2.局部对象和局部静态对象
class Time  //时间类
{
private:
    int hour;
    int minute;
    int second;
public:
    Time(int h, int m, int s); //构造函数
    ~Time();//析构函数
};
Time::Time(int h, int m, int s) //定义构造函数
{
    hour = h;
    minute = m;
    second = s;
    cout << "时间 构造函数:" << hour << ":" << minute << ":" << second << endl;
}
Time::~Time()//定义析构函数
{
    cout << "时间 析构函数: " << hour << ":" << minute << ":" << second << endl;
}

void Fun()
{
    cout << "进入Fun()" << endl;
    Time a = { 12,0,0 };
    Time b = { 13,0,0 };
    static Time c = { 14,14,14 };
    static Time d = { 15,15,15 };
    cout << "退出Fun()" << endl;
}

int main()
{
    cout << "进入main()" << endl;
    Fun();
    cout << "退出main()" << endl;

    return 0;
}

执行结果如下:

1.png

3.动态内存

动态创建对象测试如下:

//动态对象
class Time  //时间类
{
private:
    int hour;
    int minute;
    int second;
public:
    Time(int h, int m, int s); //构造函数
    ~Time();//析构函数
};
Time::Time(int h, int m, int s) //定义构造函数
{
    hour = h;
    minute = m;
    second = s;
    cout << "时间 构造函数:" << hour << ":" << minute << ":" << second << endl;
}
Time::~Time()//定义析构函数
{
    cout << "时间 析构函数: " << hour << ":" << minute << ":" << second << endl;
}

int main()
{
    cout << "进入main()" << endl;
    Time* pt1 = new Time{16,0,0};
    Time* pt2 = new Time{17,0,0};//没有delete,内存泄漏
    delete pt1;

    cout << "退出main()" << endl;
    return 0;
}

程序执行结果如下:

1.png

4.其它情况

全局变量和局部变量夹杂情况如下,程序运行结果是什么呢?

class Time  //时间类
{
private:
    int hour;
    int minute;
    int second;
public:
    Time(int h, int m, int s); //构造函数
    ~Time();//析构函数
};
Time::Time(int h, int m, int s) //定义构造函数
{
    hour = h;
    minute = m;
    second = s;
    cout << "时间 构造函数:" << hour << ":" << minute << ":" << second << endl;
}
Time::~Time()//定义析构函数
{
    cout << "时间 析构函数: " << hour << ":" << minute << ":" << second << endl;
}
class Date  //日期类
{
private:
    int year;
    int month;
    int day;
public:
    Date(int y, int m, int d); //声明构造函数
    ~Date(); //声明析构函数
}yesteday(2023, 4, 21); //定义全局对象

Date::Date(int y, int m, int d) //定义构造函数
{
    year = y;
    month = m;
    day = d;
    //在类Date定义的构造函数中定义类Time的对象(局部)
    Time time{ 11, 11, d };
    cout << "日期 构造函数: " << year << ":" << month << ":" << day << endl;
}
Date::~Date()
{
    cout << "日期 析构函数: " << year << ":" << month << ":" << day << endl;
}

int main()
{
    cout << "进入 main()" << endl;
    Date today(2023, 4, 22);
    cout << "退出 main()" << endl;

    return 0;
}

1.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/596554.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DRF的序列化【2】

【0】前提概要 【1】基于 View JsonResponse 编写的 5 个接口&#xff1a; 序列化自定义处理: 你需要自己编写序列化逻辑。处理 JSON 格式的 POST 请求数据: 从 request.body 中获取数据&#xff0c;并使用 json.loads() 解析成字典&#xff0c;然后创建相应的对象。request.…

JS基础:变量的详解

你好&#xff0c;我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端的程序媛。 云桃桃&#xff0c;大专生&#xff0c;一枚程序媛&#xff0c;感谢关注。回复 “前端基础题”&#xff0c;可免费获得前端基础 100 题汇总&#xff0c;回复 “前端基础路线”&#xff0c;可获取…

基于51单片机NEC协议红外遥控发送接收proteus仿真设计

1.主要功能&#xff1a; 设计一个51单片机红外遥控发射接收proteus仿真设计 功能要求&#xff1a; 1、使用单片机模拟红外遥控器发射红外编码&#xff1b; 2、利用从机接收红外编码&#xff0c;并将编码以16进制显示到数码管上。 需注意仿真中51单片机芯片是兼容的&#x…

Web网页项目实战-----小兔鲜儿项目

本网站是一个电商网站&#xff0c;主要由Html、CSS、JS来完成&#xff0c;实现的功能主要是可以购买产品&#xff0c;展示产品&#xff0c;查看订单等功能&#xff0c;效果如下&#xff0c;如有需要项目代码的可以私信我&#xff0c;或者文章底下评论&#xff0c;我给分享原项目…

爬虫学习(2)破解百度翻译

代码 import requests import jsonif __name__ "__main__":url https://fanyi.baidu.com/sug#post请求参数处理&#xff08;同get请求一致&#xff09;headers {"User-Agent": Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …

【C语言】第一个C程序:hello world

printf简介 printf是C语言提供的库函数&#xff0c;可以在屏幕上打印格式化数据。这里不作展开&#xff0c;只需要知道&#xff0c;如果要打印hello world&#xff0c;就把双引号引起来的"hello world"作为参数传给printf就行了。如果想要在打印后换行&#xff0c;要…

【Linux】冯·诺依曼体系结构

要想谈进程&#xff0c;我们就不能只谈进程&#xff0c;我们如果想搞清楚什么是进程&#xff0c;就要从操作系统讲起。我们现在的不管是Linux或是Windows或是安卓等操作系统&#xff0c;它们都有一个相同点&#xff0c;那就是遵循冯诺依曼体系结构&#xff0c;我们看一下冯诺依…

如何让你的排单更快?

一般我们都喜欢做打板借用快速通道&#xff01;但是目前快速通道也是共享通道&#xff0c;独立单元格基本不开发。 想要排单更快&#xff0c;想要隔夜打板&#xff0c;我们到底应该怎么做呢&#xff1f; 想要排单更快&#xff0c;说白了就是要提高你的交易速度&#xff01;一&a…

ai写作工具推荐:如何用AI人工智能进行写作

AI写作工具&#xff1a;提升创作效率的秘密武器 在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;已经渗透到我们生活的方方面面&#xff0c;包括写作。AI写作工具&#xff0c;就是利用人工智能技术&#xff0c;帮助我们进行文本生成、语言优化等工作的工…

使用C语言实现杨氏矩阵并找出数字

前言 过了五一假期&#xff0c;咋们经过了一个假期的休息&#xff0c;要继续学习了&#xff0c;不能偷懒哦&#xff01;&#xff01; 今天让我们来看看如何在一个杨氏矩阵中找出自己想找到的数字。 首先&#xff0c;我们要了解一下杨氏矩阵到底是什么&#xff0c;如果一个矩阵中…

语音识别简介

⚠申明&#xff1a; 未经许可&#xff0c;禁止以任何形式转载&#xff0c;若要引用&#xff0c;请标注链接地址。 全文共计3077字&#xff0c;阅读大概需要3分钟 &#x1f308;更多学习内容&#xff0c; 欢迎&#x1f44f;关注&#x1f440;【文末】我的个人微信公众号&#xf…

Android关于SparseArray面试题

问题1: 什么是SparseArray&#xff0c;它与HashMap有什么不同&#xff1f; 回答&#xff1a; SparseArray是一个用于优化特定情况下内存使用的数据结构&#xff0c;主要用于替代HashMap<Integer, Object>。SparseArray使用两个数组分别存储键和值&#xff0c;而不是使用…

最原理的一集——Mathtype公式编号设置(Mathtype7.8+Word)

版本 Mathtype7.8Office2019 Word 读完本文你将会 随心所欲&#xff0c;想怎么给公式编号就怎么给公式编号&#xff0c;想从(X.1)开始&#xff0c;就从(X.1)开始大概了解Mathtype公式设置原理给作者点赞 如果你想自己跟着文章做的话 请不要在自己的论文里边直接操作&#…

Docker私有仓库与Harbor部署使用

目录 一、本地私有仓库 1. 下载registry镜像 2. 在daemon.json文件中添加私有镜像仓库地址 ​编辑 3. 运行registry容器 4. Docker容器的重启策略如下 5. 为镜像打标签 6. 上传到私有仓库 7. 列出私有仓库的所有镜像 8. 列出私有仓库的centos镜像有哪些tag 9. 先删…

zTasker v1.88.1一键定时自动化任务

软件介绍 zTasker是一款完全免费支持定时、热键或条件触发的方式执行多种自动化任务的小工具&#xff0c;支持win7-11。其支持超过100种任务类型&#xff0c;50种定时/条件执行方法&#xff0c;而且任务列表可以随意编辑、排列、移动、更改类型&#xff0c;支持任务执行日志&a…

分布式锁之RedissonLock

什么是Redisson&#xff1f; 俗话说他就是看门狗&#xff0c;看门狗机制是一种用于保持Redis连接活跃性的方法&#xff0c;通常用于分布式锁的场景。看门狗的工作原理是&#xff1a;当客户端获取到锁之后&#xff0c;会对Redis中的一个特定的键设置一个有限的过期时间&#xff…

投资海外标的,首选跨境ETF!现在新开佣金低至万0.5!

全球资产配置的利器 随着经济的发展&#xff0c;全球资产配置成为中产阶级的关注方向。目前&#xff0c;全球资产配置的主要渠道包括直接开立境外账户、 QDII 基金、跨境 ETF 等。 现阶段通过跨境 ETF 投资境外股市是最便利、最具效率的方式之一。首先&#xff0c;与直接境外…

4. RedHat认证-进程管理

4. RedHat认证-进程管理 1.进程概念 进程就是正在运行中的程序或者命令 每一个进程都是运行的实体&#xff0c;都有自己的地址空间&#xff0c;并占有一定的资源空间 程序消耗的是磁盘资源、进程消耗的是内存和CPU资源 进程会占用四类资源&#xff08;CPU 、内存、磁盘、网…

会声会影电影片头怎么做 会声会影电影质感调色技巧 会声会影视频制作教程 会声会影下载免费中文版

片头通常通过一系列的图像、音乐和文字等元素来引入电影的主题和氛围。通过视觉和音频的呈现方式&#xff0c;给观众留下深刻的第一印象&#xff0c;为电影的故事铺设基础。这篇文章来学习一下会声会影电影片头怎么做&#xff0c;会声会影电影质感调色技巧。 一、会声会影电影…

力扣每日一题-拆炸弹-2024.5.5

力扣题目&#xff1a;拆炸弹 题目链接: 1652.拆炸弹 题目描述 代码思路 根据代码实现分为k等于0和k不等于0的情况。k等于0很容易处理&#xff0c;而k不等于0时&#xff0c;需要使用滑动窗口的方式来解决。先根据小于0或大于0确定一个窗口&#xff0c;然后移动&#xff0c;获…