当前位置: 首页 > 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; ​ 安装…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积

1.题目介绍 给定一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O…...