当前位置: 首页 > news >正文

4. C++构造函数和析构函数

一、对象的初始化和清理

  • C++中的面向对象来源于生活,每个对象也都会有初始设置以及对象销毁前的清理数据的设置,对象的初始化和清理也是两个非常重要的安全问题

    1. 一个对象或者变量没有初始状态,对其使用后果是未知的
    2. 使用完一个对象或变量,没有及时清理,也会造成一定的安全问题
    • 例如:生活中我们买的电子产品基本都会有出厂设置,在某一天我们不用时也会删除掉自己的信息数据以保证隐私
  • 每个对象与其他对象的区别:

    • 外在区别即对象名称
    • 内在区别则是对象自身属性值,即数据成员的值
  • 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;
}
image-20230509111435308

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 复制构造函数的三种使用情形

  1. 定义一个对象时,以本类另一个对象作为初始值

    Point a(10, 20);
    Point b = a;
    
  2. 传参

    void fun1(Point p){cout << p.getX() << endl;
    }// 调用语句
    fun1(b);
    
  3. 函数值返回

    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()
}
image-20220605223805453

四、类对象作为类成员

  • 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();
}
image-20221017005820482

相关文章:

4. C++构造函数和析构函数

一、对象的初始化和清理 C中的面向对象来源于生活&#xff0c;每个对象也都会有初始设置以及对象销毁前的清理数据的设置&#xff0c;对象的初始化和清理也是两个非常重要的安全问题 一个对象或者变量没有初始状态&#xff0c;对其使用后果是未知的使用完一个对象或变量&#x…...

【Spring Cloud 四】Ribbon负载均衡

Ribbon负载均衡 系列文章目录背景一、什么是Ribbon二、为什么要有Ribbon三、使用Ribbon进行负载均衡服务提供者A代码pom文件yml配置文件启动类controller 服务提供者Bpom文件yml配置文件启动类controller 服务消费者pom文件yml文件启动类controller 运行测试 四、Ribbon的负载均…...

“星闪”:60%能耗 6倍速度 1/30时延**

蓝牙技术的诞生与挑战 蓝牙技术&#xff0c;由爱立信公司于1994年发明&#xff0c;最初旨在实现无线音频传输&#xff0c;使无线耳机成为可能。这项技术成为过去20多年里最主流的近距离无线通讯技术&#xff0c;广泛应用于手机、耳机、手柄、键盘等设备。然而&#xff0c;尽管…...

cocosCreator 之 i18n多语言插件

版本&#xff1a; v3.4.0 环境&#xff1a; Mac 简介 i18n是国际化的简称&#xff0c; 全名&#xff1a;internationalization&#xff1b;取首尾字符i和n&#xff0c;18代表单词中间的字符数目。 该插件不需要产品做太多的改变&#xff0c;通过语言的设置&#xff0c;实现不…...

redis 如何保证数据一致性

前言 日常开发中常会使用redis作为项目中的缓存&#xff0c;只要我们使用 Redis 缓存&#xff0c;就必然会面对缓存和数据库间的一致性保证问题。而且如果数据不一致&#xff0c;那么应用从缓存中读取的数据就不是最新数据&#xff0c;可能会导致严重的业务问题。 为什么会数…...

因果推断(三)双重差分法(DID)

因果推断&#xff08;三&#xff09;双重差分法&#xff08;DID&#xff09; 双重差分法是很简单的群体效应估计方法&#xff0c;只需要将样本数据随机分成两组&#xff0c;对其中一组进行干预。在一定程度上减轻了选择偏差带来的影响。 因果效应计算&#xff1a;对照组y在干预…...

neo4j入门实例介绍

使用Cypher查询语言创建了一个图数据库&#xff0c;其中包含了电影《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

参考&#xff1a; https://docs.docker.com/engine/install/ubuntu/ 支持的Ubuntu版本&#xff1a; Ubuntu Lunar 23.04Ubuntu Kinetic 22.10Ubuntu Jammy 22.04 (LTS)Ubuntu Focal 20.04 (LTS) 1 卸载旧版本 非官方的安装包&#xff0c;需要先卸载&#xff1a; docker.io…...

电脑维护进阶:让你的“战友”更强大、更持久!

前言 无论是学习还是工作&#xff0c;电脑已经成为了IT人必不可少的得力助手。然而&#xff0c;电脑的性能和寿命需要经过细心的维护来保证。本文将详细探讨如何维护你的电脑&#xff0c;延长它的寿命&#xff0c;以及一些实用建议。 硬件保养篇 内部清洁 灰尘会导致电脑散热…...

【Leetcode】75.颜色分类

一、题目 1、题目描述 给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。 必须在不使用库内置的 sort 函数的情况下解决这个问…...

Pytesseract学习笔记

函数 pytesseract.image_to_string(image: Any, lang: Any None, …) 识别图像中的文本。 Parameters image(Any)&#xff1a;输入图像&#xff0c;不接受bytes类型。...

cnvd通用型证书获取姿势

因为技术有限&#xff0c;只能挖挖不用脑子的漏洞&#xff0c;平时工作摸鱼的时候通过谷歌引擎引擎搜索找找有没有大点的公司有sql注入漏洞&#xff0c;找的方法就很简单&#xff0c;网站结尾加上’&#xff0c;有异常就测试看看&#xff0c;没有马上下一家&#xff0c;效率至上…...

elasticsearch的副本和分片的区别

es/elasticsearch的副本和分片的区别 一&#xff1a;概念 &#xff08;1&#xff09;集群&#xff08;Cluster&#xff09;&#xff1a; ES可以作为一个独立的单个搜索服务器。不过&#xff0c;为了处理大型数据集&#xff0c;实现容错和高可用性&#xff0c;ES可以运行在许多互…...

Docker部署Gitlab

Docker部署Gitlab 文章目录 Docker部署Gitlab前置环境部署步骤初始化配置文件80端口部署方式&#xff08;二选一&#xff09;非80端口需要的部署方式&#xff08;二选一&#xff09;修改 gitlab.rb修改 gitlab.yml刷新配置 前置环境 docker 19.03.13 es 7.2.0 部署步骤 初始…...

ABeam News | ABeam大中华区新人入社式,开启崭新的职场探索之旅吧!

ABeam News | ABeam大中华区新人入社式&#xff0c;开启崭新的职场探索之旅吧&#xff01; 隔空投送 很高兴认识你 7月3日&#xff0c;FY24 ABeam大中华区新人入社式在西安隆重举办&#xff0c;ABeam大中华区董事长兼总经理中野洋辅先生专程莅临入社式现场&#xff0c;与89名…...

【C++】开源:sqlite3数据库配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍sqlite3数据库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下…...

[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基本语法 文件名代换 用于匹配的字符称为通配符&#xff08;Wildcard&#xff09;&#xff0c;如&#xff1a;* ? [ ] 具体如下&#xff1a; *…...

Unity之webgl端通过vue3接入腾讯云联络中心SDK

腾讯云联络中心SDK:云联络中心 Web-SDK 开发指南-文档中心-腾讯云 (tencent.com) 1 首先下载Demo ​ 1.1 对其进行解压 ​ 1.2根据文档操作 查看README.md,根据说明设置server下的dev.js里的相关参数。 然后打开电脑终端&#xff0c;cd到项目的路径&#xff1a; ​ 安装…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域&#xff1a;无处不在的数字助手 2、 计算机的进化史&#xff1a;从算盘到量子计算 3、计算机的分类&#xff1a;不止 “台式机和笔记本” 4、计算机的组件&#xff1a;硬件与软件的协同 4.1 硬件&#xff1a;五大核心部件 4.2 软件&#…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...