4. C++构造函数和析构函数
一、对象的初始化和清理
-
C++中的面向对象来源于生活,每个对象也都会有初始设置以及对象销毁前的清理数据的设置,对象的初始化和清理也是两个非常重要的安全问题
- 一个对象或者变量没有初始状态,对其使用后果是未知的
- 使用完一个对象或变量,没有及时清理,也会造成一定的安全问题
- 例如:生活中我们买的电子产品基本都会有出厂设置,在某一天我们不用时也会删除掉自己的信息数据以保证隐私
-
每个对象与其他对象的区别:
- 外在区别即对象名称
- 内在区别则是对象自身属性值,即数据成员的值
-
C++利用构造函数和析构函数解决上述问题,这两个函数会被编译器自动调用,完成对象初始化和清理工作
- 对象的初始化和清理工作是编译器强制要我们做的事情,如果没有提供构造和析构,编译器会提供该函数的空实现
- 构造函数:创建对象时,为对象的成员属性赋值
- 析构函数:对象销毁前,系统自动调用,执行一些清理工作
二、构造函数(constructor)
2.1 构造函数的定义形式
类名(参数说明){初始化代码
}
2.2 构造函数的特点
- 构造函数的名字必须与类的名字相同;
- 定义构造函数时不能指定返回类型;
- 构造函数的代码与其他函数一样,但一般不直接调用(不显示调用);
- 创建类的一个新对象时,会隐式地自动调用构造函数。即当程序中声明一个新对象时,程序会自动调用该对象所属类中定义的构造函数来初始化这个对象的状态;
- 若在定义类时没有定义构造函数,C++会自动为该类创建一个缺省(default)的构造函数。该缺省构造函数没有任何形式参数,且函数体为空。
例子:
# include <iostream>
using namespace std;// 对象的初始化和清理
// 构造函数 进行初始化操作
// 析构函数,进行清理操作
class Person {
public://定义构造函数,编译器自动调用Person() {cout << "Person 构造函数调用" << endl;}//定义析构函数,自动调用~Person() {cout << "Person 析构函数调用" << endl;}
};int main() {Person p;
}
2.3 有参构造函数和无参构造函数
- 构造函数定义中,在冒号之后、函数体之前是初始化列表
- 有参构造函数:定义构造函数时带有形参,那么建立对象时必须要给出初始值,用于作为调用构造函数时的实参
- 调用时可以不需要参数的构造函数都是无参构造函数,也称为默认构造函数
- 当不定义构造函数时,编译器自动产生默认构造函数
- 在类中可以自定义无参数的构造函数,也是默认构造函数
- 全部参数都有默认形参值的构造函数也是默认构造函数
- 一个系统只能有一个默认构造函数
示例:
#include <iostream>
using namespace std; class Clock{
public:// 定义了两个Clock构造函数,即为构造函数的重载Clock(int newH, int newM, int newS); // 定义有参构造函数Clock(); // 定义无参构造函数/*// 每个参数都有默认值,属于默认构造参数Clock(int newH = 0, int newM = 0, int newS = 0);调用方式:Clock c1(8, 30, 30);Clock c2(8);Clock c3; // 这种方式也可以使用Clock()定义无参构造函数,因此类中不可同时存在这两种构造函数的定义方式*/void setTime(int newH, int newM, int newS);void showTime();
private:int hour, minute, second;
};// 有参构造函数的实现
// 冒号之后,函数体之前部分称为 初始化成员列表
// 将初始化传入的三个数据newH、newM、newS的值分别给hour、minute、second
Clock::Clock(int newH, int newM, int newS):hour(newH), minute(newM), second(newS){
}
/* 等价于
Clock::Clock(int newH, int newM, int newS){hour = newH;minute = newM;second = newS;
}
*/// 无参构造函数的实现
Clock::Clock(): hour(1), minute(1), second(1){
}
/* 等价于
Clock::Clock(){hour = 1;minute = 1;second = 1;
}
*/// 成员函数
void Clock::setTime(int newH, int newM, int newS){hour = newH;minute = newM;second = newS;
}
void Clock::showTime(){cout << hour << ":" << minute << ":" << second << endl;
}int main(){Clock myClock1; // 定义对象,此时自动调用无参构造函数myClock1.showTime();Clock myClock2(8, 3, 30); // 定义对象,此时自动调用有参构造函数myClock2.showTime();return 0;
}
2.4 复制构造函数
-
具有一般构造函数的所有特性,其形参是本类的对象的引用
-
作用:使用一个已经存在的对象,该对象由复制构造函数的形参指定,去初始化 同类 的一个新对象
-
语法:
class 类名 { public:类名(形参表); // 构造函数类名(类名 &对象名); // 复制构造函数... };// 复制构造函数的定义 类名::类名(类名 &对象名){ } -
类内声明,类外实现
2.4.1 复制构造函数的三种使用情形
-
定义一个对象时,以本类另一个对象作为初始值
Point a(10, 20); Point b = a; -
传参
void fun1(Point p){cout << p.getX() << endl; }// 调用语句 fun1(b); -
函数值返回
Point fun2(){return Point(1, 2); }// 调用语句 b = fun2();
三、析构函数(destructor)
3.1 析构函数的定义形式
~类名() {}
3.2 析构函数的特点
- 析构函数的名字必须是在类名前加上一个波纹号“~”,以区别于构造函数;
- 定义析构函数时也不能指定返回类型;
- 在对象消亡时,隐式地自动调用析构函数。即当程序中一个对象作用结束时,程序会自动调用该对象所属类中定义的析构函数来清除这个对象所占的存储空间;
- 若在定义类时没有定义析构函数,C++会自动为该类创建一个缺省的析构函数。这个缺省析构函数没有任何形式参数,且函数体为空。
3.3 析构函数的实现
#include <iostream>
using namespace std;class DemoClass{
public:DemoClass(int i); // 函数名与类名一样,因此是构造函数~DemoClass(); // 函数名与类名一样,且开头有~,因此是析构函数
};// 构造函数的实现
DemoClass::DemoClass(int i){cout << "Initial value is" << i << endl;
}// 析构函数的实现
DemoClass::~DemoClass(){cout << "destructor" << endl;
}void main(){DemoClass obj(30); // 创建对象,同时自动调用构造函数DemoClass()cout << "This is the end main()" << endl;return; // 函数执行结束,创建的对象生命结束,自动调用析构函数~DemoClass()
}
四、类对象作为类成员
- C++类中的成员可以是另一个类的对象,称该成员为对象成员
- 例如:B类中有对象A作为成员,A为对象成员
class A{}
class B{A a;
}
- 创建B对象时,A与B的构造和析构的顺序:
- 构造顺序:先调用对象成员的构造,再调用本类的构造
- 析构顺序:与构造顺序相反
# 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: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();
}

相关文章:
4. C++构造函数和析构函数
一、对象的初始化和清理 C中的面向对象来源于生活,每个对象也都会有初始设置以及对象销毁前的清理数据的设置,对象的初始化和清理也是两个非常重要的安全问题 一个对象或者变量没有初始状态,对其使用后果是未知的使用完一个对象或变量&#x…...
【Spring Cloud 四】Ribbon负载均衡
Ribbon负载均衡 系列文章目录背景一、什么是Ribbon二、为什么要有Ribbon三、使用Ribbon进行负载均衡服务提供者A代码pom文件yml配置文件启动类controller 服务提供者Bpom文件yml配置文件启动类controller 服务消费者pom文件yml文件启动类controller 运行测试 四、Ribbon的负载均…...
“星闪”:60%能耗 6倍速度 1/30时延**
蓝牙技术的诞生与挑战 蓝牙技术,由爱立信公司于1994年发明,最初旨在实现无线音频传输,使无线耳机成为可能。这项技术成为过去20多年里最主流的近距离无线通讯技术,广泛应用于手机、耳机、手柄、键盘等设备。然而,尽管…...
cocosCreator 之 i18n多语言插件
版本: v3.4.0 环境: Mac 简介 i18n是国际化的简称, 全名:internationalization;取首尾字符i和n,18代表单词中间的字符数目。 该插件不需要产品做太多的改变,通过语言的设置,实现不…...
redis 如何保证数据一致性
前言 日常开发中常会使用redis作为项目中的缓存,只要我们使用 Redis 缓存,就必然会面对缓存和数据库间的一致性保证问题。而且如果数据不一致,那么应用从缓存中读取的数据就不是最新数据,可能会导致严重的业务问题。 为什么会数…...
因果推断(三)双重差分法(DID)
因果推断(三)双重差分法(DID) 双重差分法是很简单的群体效应估计方法,只需要将样本数据随机分成两组,对其中一组进行干预。在一定程度上减轻了选择偏差带来的影响。 因果效应计算:对照组y在干预…...
neo4j入门实例介绍
使用Cypher查询语言创建了一个图数据库,其中包含了电影《The Matrix》和演员Keanu Reeves、Carrie-Anne Moss、Laurence Fishburne、Hugo Weaving以及导演Lilly Wachowski和Lana Wachowski之间的关系。 CREATE (TheMatrix:Movie {title:The Matrix, released:1999,…...
CGAL-2D和3D线性几何内核-点和向量-内核扩展
文章目录 1.介绍1.1.鲁棒性 2.内核表示2.1.通过参数化实现泛型2.2.笛卡尔核2.3.同质核2.4.命名约定2.5.内核作为trait类2.6.选择内核和预定义内核 3.几何内核3.1.点与向量3.2.内核对象3.3.方位和相对位置 4.谓语和结构4.1.谓词4.2.结构4.3.交集和变量返回类型4.4.例子4.5.构造性…...
Ubuntu 22.04 安装docker
参考: https://docs.docker.com/engine/install/ubuntu/ 支持的Ubuntu版本: Ubuntu Lunar 23.04Ubuntu Kinetic 22.10Ubuntu Jammy 22.04 (LTS)Ubuntu Focal 20.04 (LTS) 1 卸载旧版本 非官方的安装包,需要先卸载: docker.io…...
电脑维护进阶:让你的“战友”更强大、更持久!
前言 无论是学习还是工作,电脑已经成为了IT人必不可少的得力助手。然而,电脑的性能和寿命需要经过细心的维护来保证。本文将详细探讨如何维护你的电脑,延长它的寿命,以及一些实用建议。 硬件保养篇 内部清洁 灰尘会导致电脑散热…...
【Leetcode】75.颜色分类
一、题目 1、题目描述 给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。 必须在不使用库内置的 sort 函数的情况下解决这个问…...
Pytesseract学习笔记
函数 pytesseract.image_to_string(image: Any, lang: Any None, …) 识别图像中的文本。 Parameters image(Any):输入图像,不接受bytes类型。...
cnvd通用型证书获取姿势
因为技术有限,只能挖挖不用脑子的漏洞,平时工作摸鱼的时候通过谷歌引擎引擎搜索找找有没有大点的公司有sql注入漏洞,找的方法就很简单,网站结尾加上’,有异常就测试看看,没有马上下一家,效率至上…...
elasticsearch的副本和分片的区别
es/elasticsearch的副本和分片的区别 一:概念 (1)集群(Cluster): ES可以作为一个独立的单个搜索服务器。不过,为了处理大型数据集,实现容错和高可用性,ES可以运行在许多互…...
Docker部署Gitlab
Docker部署Gitlab 文章目录 Docker部署Gitlab前置环境部署步骤初始化配置文件80端口部署方式(二选一)非80端口需要的部署方式(二选一)修改 gitlab.rb修改 gitlab.yml刷新配置 前置环境 docker 19.03.13 es 7.2.0 部署步骤 初始…...
ABeam News | ABeam大中华区新人入社式,开启崭新的职场探索之旅吧!
ABeam News | ABeam大中华区新人入社式,开启崭新的职场探索之旅吧! 隔空投送 很高兴认识你 7月3日,FY24 ABeam大中华区新人入社式在西安隆重举办,ABeam大中华区董事长兼总经理中野洋辅先生专程莅临入社式现场,与89名…...
【C++】开源:sqlite3数据库配置使用
😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍sqlite3数据库配置使用。 无专精则不能成,无涉猎则不能通。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下…...
[Docker实现测试部署CI/CD----Jenkins集成相关服务器(3)]
目录 7、 Jenkins 集成 SonarQubeJenkins 中安装 SonarScanner下载移动修改配置文件 8、Jenkins配置SonarQube安装插件添加SonarQube添加 SonarScanner 9、Jenkins集成目标服务器 7、 Jenkins 集成 SonarQube Jenkins 中安装 SonarScanner SonarScanner 是一种代码扫描工具&am…...
【Shell】基础语法(二)
文章目录 一、Shell基本语法文件名代换命令代换算术代换转义字符引号 二、Shell脚本语法条件测试分支结构循环 三、总结 一、Shell基本语法 文件名代换 用于匹配的字符称为通配符(Wildcard),如:* ? [ ] 具体如下: *…...
Unity之webgl端通过vue3接入腾讯云联络中心SDK
腾讯云联络中心SDK:云联络中心 Web-SDK 开发指南-文档中心-腾讯云 (tencent.com) 1 首先下载Demo 1.1 对其进行解压 1.2根据文档操作 查看README.md,根据说明设置server下的dev.js里的相关参数。 然后打开电脑终端,cd到项目的路径: 安装…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
记一次spark在docker本地启动报错
1,背景 在docker中部署spark服务和调用spark服务的微服务,微服务之间通过fegin调用 2,问题,docker容器中服务器来后,注册中心都有,调用服务也正常,但是调用spark启动任务后报错,报错…...
