C++ 对象的初始化和清理:构造函数和析构函数
目录
构造函数和析构函数
构造函数
析构函数
构造函数的分类及调用
括号法
显示法
隐式转换法
拷贝构造函数的调用时机
使用一个已经创建完毕的对象来初始化一个新对象
值传递的方式给函数参数传值
以值方式返回局部对象
构造函数调用规则
初始化列表
类对象作为其他类成员 各类的构造和析构执行顺序
构造函数和析构函数
构造函数
主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。
构造函数语法:类名(){}
- 构造函数,没有返回值也不写void
- 函数名称与类名相同
- 构造函数可以有参数,因此可以发生重载
- 程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次
析构函数
主要作用在于对象**销毁前**系统自动调用,执行一些清理工作。
析构函数语法:~类名(){}
- 析构函数,没有返回值也不写void
- 函数名称与类名相同,在名称前加上符号 ~
- 析构函数不可以有参数,因此不可以发生重载
- 程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次
构造和析构都是必须有的实现,如果我们自己不提供,编译器会提供一个空实现的构造和析构
class Person {public:/* 构造函数 */Person() {cout << "我是构造函数" << endl; // 我是构造函数}/* 细狗函数 */~Person() {cout << "我是细狗函数" << endl; // 我是细狗函数(system("pause")在的情况,不会执行,因为代码还没走完,不会去销毁类)}
};int main() {class Person zhanghai;system("pause");return 0;
}
构造函数的分类及调用
两种分类方式:
- 按参数分为: 有参构造和无参构造(默认构造)
- 按类型分为: 普通构造和拷贝构造
三种调用方式:
- 括号法
- 显示法
- 隐式转换法
括号法
class Person {
public:int age;Person() {cout << "Person的无参构造函数调用" << endl;}Person(int a) {age = a;cout << "Person的有参构造函数调用" << endl;}Person(const Person &p) { //将传入的人身上的所有属性,拷贝到我身上age = p.age;cout << "Person的拷贝构造函数调用" << endl;}~Person() {cout << "Person的细狗函数" << endl;}
};class Person p1; // 默认 无参构造函数的调用 (调用默认的无参构造时,不要加小括号)
class Person p2(1); // 有参构造函数的调用
class Person p3(p2); // 拷贝构造函数的调用
cout << p2.age << endl; // 10
cout << p3.age << endl; // 10
显示法
class Person {
public:int age;Person() {cout << "Person的无参构造函数调用" << endl;}Person(int a) {age = a;cout << "Person的有参构造函数调用" << endl;}Person(const Person &p) { //将传入的人身上的所有属性,拷贝到我身上age = p.age;cout << "Person的拷贝构造函数调用" << endl;}~Person() {cout << "Person的细狗函数" << endl;}
};Person p1;
Person p2 = Person(10); // 有参构造
Person p3 = Person(p2); // 拷贝构造Person(10); // 匿名对象,特点:当前行执行结束后,系统会立即回收掉匿名对象
cout << "我的上一句输出是 Person的细狗函数" << endl;
Person(p3); // 不要利用拷贝构造函数初始化对象,编辑器会认为 Person(p3) == Person p3
隐式转换法
class Person {
public:int age;Person() {cout << "Person的无参构造函数调用" << endl;}Person(int a) {age = a;cout << "Person的有参构造函数调用" << endl;}Person(const Person &p) { //将传入的人身上的所有属性,拷贝到我身上age = p.age;cout << "Person的拷贝构造函数调用" << endl;}~Person() {cout << "Person的细狗函数" << endl;}
};Person p4 = 10; // 有参构造 相当于 Person p4 = Person(10)
Person p5 = p4; // 拷贝构造 相当于 Person p5 = Person(p4)
拷贝构造函数的调用时机
C++中拷贝构造函数调用时机通常有三种情况
- 使用一个已经创建完毕的对象来初始化一个新对象
- 值传递的方式给函数参数传值
- 以值方式返回局部对象
使用一个已经创建完毕的对象来初始化一个新对象
class Person {
public:Person() {cout << "无参构造函数!" << endl;mAge = 0;}Person(int age) {cout << "有参构造函数!" << endl;mAge = age;}Person(const Person& p) {cout << "拷贝构造函数!" << endl;mAge = p.mAge;}//析构函数在释放内存之前调用~Person() {cout << "析构函数!" << endl;}
public:int mAge;
};void test01() {Person man(100); //p对象已经创建完毕Person newman(man); //调用拷贝构造函数Person newman2 = man; //拷贝构造//Person newman3;//newman3 = man; //不是调用拷贝构造函数,赋值操作
}
值传递的方式给函数参数传值
class Person {
public:Person() {cout << "无参构造函数!" << endl;mAge = 0;}Person(int age) {cout << "有参构造函数!" << endl;mAge = age;}Person(const Person& p) {cout << "拷贝构造函数!" << endl;mAge = p.mAge;}//析构函数在释放内存之前调用~Person() {cout << "析构函数!" << endl;}
public:int mAge;
};void doWork(Person p1) { //相当于Person p1 = p;}
void test02() {Person p; //无参构造函数doWork(p);
}
以值方式返回局部对象
class Person {
public:Person() {cout << "无参构造函数!" << endl;mAge = 0;}Person(int age) {cout << "有参构造函数!" << endl;mAge = age;}Person(const Person& p) {cout << "拷贝构造函数!" << endl;mAge = p.mAge;}//析构函数在释放内存之前调用~Person() {cout << "析构函数!" << endl;}
public:int mAge;
};Person doWork2()
{Person p1;cout << (int *)&p1 << endl;return p1; // 返回的是p1的副本,跟p1毫无干系,只是相同而已
}void test03()
{Person p = doWork2(); // Person p = p1cout << (int *)&p << endl;
}int main() {/*依次输出:无参构造函数ff44aaff拷贝构造函数析构函数ff55aacc析构函数*/test03();return 0;
}
构造函数调用规则
默认情况下,c++编译器至少给一个类添加3个函数
- 默认构造函数(无参,函数体为空)
- 默认析构函数(无参,函数体为空)
- 默认拷贝构造函数,对属性进行值拷贝
构造函数调用规则如下:
- 如果用户定义有参构造函数,c++不在提供默认无参构造,但是会提供默认拷贝构造
- 如果用户定义拷贝构造函数,c++不会再提供其他构造函数、
#include <iostream>
using namespace std;class Person {
public://无参(默认)构造函数Person() {cout << "无参构造函数!" << endl;}//有参构造函数Person(int a) {age = a;cout << "有参构造函数!" << endl;}//拷贝构造函数//Person(const Person& p) {// age = p.age;// cout << "拷贝构造函数!" << endl;//}//析构函数~Person() {cout << "析构函数!" << endl;}
public:int age;
};void test01()
{Person p1(18);//如果不写拷贝构造,编译器会自动添加拷贝构造,并且做浅拷贝操作Person p2(p1);cout << "p2的年龄为: " << p2.age << endl;
}void test02()
{//如果用户提供有参构造,编译器不会提供默认构造,会提供拷贝构造Person p1; //此时如果用户自己没有提供默认构造,会出错Person p2(10); //用户提供的有参Person p3(p2); //此时如果用户没有提供拷贝构造,编译器会提供//如果用户提供拷贝构造,编译器不会提供其他构造函数Person p4; //此时如果用户自己没有提供默认构造,会出错Person p5(10); //此时如果用户自己没有提供有参,会出错Person p6(p5); //用户自己提供拷贝构造
}int main() {/*注释掉 拷贝构造函数 的情况有参构造函数!p2的年龄为: 18析构函数!析构函数!*/test01();return 0;
}
初始化列表
C++用来初始化属性 ——`构造函数():属性1(值1),属性2(值2)... {}
class Person {
public:传统方式初始化//Person(int a, int b, int c) {// m_A = a;// m_B = b;// m_C = c;//}//初始化列表方式初始化,注意冒号的位置Person(int a, int b, int c) :m_A(a), m_B(b), m_C(c) {}void PrintPerson() {cout << "mA:" << m_A << endl; // 1cout << "mB:" << m_B << endl; // 2cout << "mC:" << m_C << endl; // 3}
private:int m_A;int m_B;int m_C;
};int main() {Person p(1, 2, 3);p.PrintPerson();return 0;
}
类对象作为其他类成员 各类的构造和析构执行顺序
构造的顺序是 :
先调用对象成员的构造,再调用本类构造
析构顺序与构造相反
#include <iostream>
#include <string>
using namespace std;class Phone
{
public:Phone(string name){m_PhoneName = name;cout << "Phone构造" << endl;}~Phone(){cout << "Phone析构" << endl;}string m_PhoneName;};class Person
{
public:// 初始化列表可以告诉编译器调用哪一个构造函数 Phone m_Phone = pName => Phone m_Phone = Phone(pName) 有参构造Person(string name, string pName) :m_Name(name), m_Phone(pName){cout << "Person构造" << endl;}~Person(){cout << "Person析构" << endl;}void playGame(){cout << m_Name << " 使用" << m_Phone.m_PhoneName << " 牌手机! " << endl;}string m_Name;Phone m_Phone;};
void test01()
{// 当类中成员是其他类对象时,我们称该成员为 对象成员// 构造的顺序是 :先调用对象成员的构造,再调用本类构造// 析构顺序与构造相反Person p("张三", "苹果X");p.playGame();}int main() {test01();return 0;
}
相关文章:
C++ 对象的初始化和清理:构造函数和析构函数
目录 构造函数和析构函数 构造函数 析构函数 构造函数的分类及调用 括号法 显示法 隐式转换法 拷贝构造函数的调用时机 使用一个已经创建完毕的对象来初始化一个新对象 值传递的方式给函数参数传值 以值方式返回局部对象 构造函数调用规则 初始化列表 类对象作…...
Tmux中使用Docker报错 - 解决方案
问题 进入Tmux会话后,在其中使用Docker可能会出现如下报错: Got permission denied while trying to connect to the Docker ……解决方案 退出tmux会话: tmux detach在tmux会话外部杀掉tmux进程: pkill -f tmux重新进入tmux:…...
如何在WordPress中批量替换图片路径?
很多站长在使用WordPress博客或者搬家时,需要把WordPress文章中的图片路径进行替换来解决图片不显示的问题。总结一下WordPress图片路径批量替换的过程,方便有此类需求的站长们学习。 什么情况下批量替换图片路径 1、更换了网站域名 有许多网站建设初期…...
el-pagination 纯前端分页
需求:后端把所有数据都返给前端,前端进行分页渲染。 实现思路:先把数据存储到一个大数组中,然后调用方法进行切割。主要使用数组的slice方法 所有代码: html <template><div style"padding: 20px&qu…...
基于springboot的校园二手市场
博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…...
【开源】基于Vue和SpringBoot的在线课程教学系统
项目编号: S 014 ,文末获取源码。 \color{red}{项目编号:S014,文末获取源码。} 项目编号:S014,文末获取源码。 目录 一、摘要1.1 系统介绍1.2 项目录屏 二、研究内容2.1 课程类型管理模块2.2 课程管理模块2…...
Mysql分布式集群部署---MySQL集群Cluster将数据分成多个片段,每个片段存储在不同的服务器上
1.1 目的 部署MysqlCluster集群环境 1.2 MySQL集群Cluster原理 1 数据分片 MySQL集群Cluster将数据分成多个片段,每个片段存储在不同的服务器上。这样可以将数据负载分散到多个服务器上,提高系统的性能和可扩展性。 2. 数据同步 MySQL集群Cluster使…...
身份认证技术
身份认证是对系统的用户进行有效性、真实性验证。 1.口令认证方式 使用口令认证方式,用户必须具有一个唯一的系统标识,并且保证口令在系统的使用和存储过程中是安全的,同时口令在传输过程中不能被窃取、替换。另外特别要注意的是在…...
Centos7、Mysql8.0 load_file函数返回为空的终极解决方法--暨selinux的深入理解
零、问题背景 最近想换房,为了方便自己对比感兴趣的房子,因此决定将目标房源的基本信息放在表里,特别是要一目了然的看到众多房子的各种图纸和照片,因此决定要在Mysql8.0.34数据库中以二进制形式保存图片(抛开合理性和…...
基于Spring Boot的水产养殖管理系统
文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于Spring Boot的水产养殖管理系统,jav…...
LCR 090. 打家劫舍 II(leetcode)动态规划
文章目录 前言一、题目分析二、算法原理1.状态表示2.状态转移方程3.初始化4.填表顺序5.返回值是什么 三、代码实现总结 前言 在本文章中,我们将要详细介绍一下LeetcodeLCR 090. 打家劫舍 II。采用动态规划解决,这是一道经典的多状态dp问题 一、题目分析…...
【小沐学Python】Python实现语音识别(Whisper)
文章目录 1、简介1.1 whisper简介1.2 whisper模型 2、安装2.1 whisper2.2 pytorch2.3 ffmpeg 3、测试3.1 命令测试3.2 代码测试:识别声音文件3.3 代码测试:实时录音识别 结语 1、简介 https://github.com/openai/whisper 1.1 whisper简介 Whisper 是…...
Nginx负载均衡实战
🎵负载均衡组件 ngx_http_upstream_module https://nginx.org/en/docs/http/ngx_http_upstream_module.html upstream模块允许Nginx定义一组或多组节点服务器组,使用时可以通过多种方式去定义服务器组 样例: upstream backend {server back…...
Redis skiplist源码解析(支持范围查询)
跳表是一个多层的有序链表,在跳表中进行查询操作时,查询代码可以从最高层开始查询。层数越高,结点数越少,同时高层结点的跨度会比较大。因此,在高层查询结点时,查询一个结点可能就已经查到了链表的中间位置…...
MVSNeRF:多视图立体视觉的快速推广辐射场重建(2021年)
MVSNeRF:多视图立体视觉的快速推广辐射场重建(2021年) 摘要1 引言2 相关工作3 MVSNeRF实现方法3.1 构建代价体3.2 辐射场的重建3.3 体渲染和端到端训练 3.4 优化神经编码体 Anpei Chen and Zexiang Xu and Fuqiang Zhao et al. MVSNeRF: Fast…...
华为OD机试真题-CPU算力分配-2023年OD统一考试(C卷)
题目描述: 现有两组服务器A和B,每组有多个算力不同的CPU,其中A[i]是A组第i个CPU的运算能力,B[i]是B组第i个CPU的运算能力。一组服务器的总算力是各CPU的算力之和。为了让两组服务器的算力相等,允许从每组各选出一个CPU进行一次交换,求两组服务器中,用于交换的CPU的算力,…...
校验数据是否重叠(各种操作符>,<,>=,<=,or,and)
最近接到一个需求,其中部分功能涉及到数据的重叠校验,并且录入的数据需要包含各种操作符。如果只通过java代码来查询并进行循环判断的话,判断情况会很复杂,幸好有同事的帮忙提供了一个用sql查询重叠部分的方法,现在分享…...
大一C语言作业 12.8
1.C 对一维数组初始化时,如果全部元素都赋了初值,可以省略数组长度。 这里没有指定数组长度,编译器会根据初始化列表的元素个数来确定数组长度。 2.C 在C语言中,字符数组是不能用赋值运算符直接赋值的。 3.C 在二维数组a中&#x…...
ELasticsearch:什么是语义搜索?
语义搜索定义 语义搜索是一种解释单词和短语含义的搜索引擎技术。 语义搜索的结果将返回与查询含义匹配的内容,而不是与查询中的单词字面匹配的内容。 语义搜索是一组搜索引擎功能,其中包括根据搜索者的意图及其搜索上下文理解单词。 此类搜索旨在通过…...
ooTD I 女儿是自己的,尽情打扮尽情可爱
分享女宝的时尚穿搭 奶乎乎的黄色也太好看了 超足充绒量+优质面料 柔软蓬松上身体验感超赞 怎么穿都好看系列 轻轻松松打造时尚造型!!...
3步解决洛雪音乐播放问题:六音音源修复完整指南
3步解决洛雪音乐播放问题:六音音源修复完整指南 【免费下载链接】New_lxmusic_source 六音音源修复版 项目地址: https://gitcode.com/gh_mirrors/ne/New_lxmusic_source 你是否遇到过洛雪音乐升级后无法播放歌曲的困扰?点击播放按钮只有加载动画…...
K6压测脚本实战:从玩具到生产级性能验证手术刀
1. 为什么你写的“压测脚本”从来跑不出真实瓶颈? 上周帮一个做 SaaS 后台的团队复盘线上服务抖动问题,他们很笃定地说:“我们做过压测,QPS 5000 没问题。”我问:“用什么工具?脚本怎么写的?”对…...
FinML-Chain:融合链上链下数据,构建可信金融机器学习数据集
1. 项目概述:当区块链数据遇见机器学习 在金融科技这个日新月异的领域,我们每天都在和数据打交道。无论是高频交易、风险评估还是市场预测,机器学习模型早已成为我们手中不可或缺的“利器”。但干这行久了,你一定会遇到一个绕不开…...
科技助力,具身智能体在幼儿园科技启蒙中的应用
具身机器人通过互动式学习、多感官体验和情境化教学,为幼儿科技启蒙提供创新支持。其应用可围绕以下方向展开:互动游戏设计 开发基于肢体动作的交互游戏,如通过机器人模仿幼儿舞蹈动作,激发参与兴趣。语言与逻辑训练 利用机器人讲…...
Exchange渗透:从邮件服务器到AD特权代理的系统化利用
1. 为什么Exchange渗透不是“扫个端口爆破邮箱”就完事了?很多人一听到“Exchange渗透”,脑子里立刻跳出几个关键词:OWA登录页、Autodiscover、EWS接口、NTLM中继、ProxyLogon——然后顺手丢个nuclei模板去扫,再跑一遍爆破脚本&am…...
ARMv8-A架构调试机制:断点与观察点实现原理
1. AArch64调试机制概述在ARMv8-A架构中,调试功能通过硬件断点和观察点实现程序执行流的精确控制。这些机制依赖于一组专用寄存器,主要包括:断点控制寄存器(DBGBCR_EL1)断点值寄存器(DBGBVR_EL1)观察点控制寄存器(DBGWCR_EL1)观察点值寄存器(…...
Codex入门18-批量文件操作(效率神器:一句话批量重命名、格式化、清理几百个文件)
Codex入门18-批量文件操作(效率神器:一句话批量重命名、格式化、清理几百个文件) 📌 文章简介:手动改100个文件名?逐个格式化代码?一个个加版权声明?这些重复劳动该结束了。本文带你用 Codex CLI 一句话搞定批量重命名、批量格式化、批量添加文件头注释、批量清理垃圾…...
交通顶刊TR Part C 2026年6月论文导读(下)
一期刊简介Transportation Research Part C (TR-C): Emerging Technologies 是交通领域顶刊,由 Elsevier 出版,中科院与 JCR 均为 1 区,近年影响因子约8–9.6。该期刊以交通系统为核心,聚焦 AI、大数据、运筹学等新兴技术对交通规…...
2026年智传民韵Scratch图形化编程(小学组4-6年级)模拟卷(一)以及答案
2026年智传民韵Scratch图形化编程(小学组4-6年级)模拟卷(一) 考试时间:60分钟 总分:100 及格分:60 一、单选题 (共15题,每题5分) 1、嫦娥奔月”:按照以下程序运行: A:(100, 25) B:(1, 100) C:(120, 50) D:(80, 30) 【正确答案】 A 【试题解析】 2…...
OpenClaw强势推出V2026.5.20版本地部署最新教程来啦!3分钟一键安装中文版可视化操作指南
凌晨两点,我刚把 OpenClaw 跑通。看着屏幕上终于亮起来的 WebChat 界面,心里那叫一个舒坦。说实话,之前装了几次都没成功,不是端口冲突就是 API Key 配置不对,折腾了大半天。后来静下心来把文档从头到尾看了一遍&#…...
