第二层:对象的初始化和清理

news2024/9/26 3:22:36

文章目录

  • 前情回顾
  • 对象特性——对象的初始化和清理
    • 构造函数和析构函数
      • 什么是构造函数和析构函数
      • 构造函数
        • 构造函数的语法
        • 构造函数的分类
          • 按照参数分类
          • 按照类型分类
            • 拷贝构造函数
            • 拷贝函数的调用时机
            • 深拷贝和浅拷贝
        • 构造函数的调用方法
          • 括号法
          • 显示法
          • 隐式转换法
        • 构造函数规则
      • 析构函数
        • 析构函数的语法
        • 析构函数的作用
    • 初始化列表
      • 作用
      • 语法
    • 类对象作为类成员
    • 静态成员
      • 静态成员变量
        • 静态成员变量特点
      • 静态成员函数
        • 访问方式
        • 注意事项
  • 掌握对象初始化和清理,步入第三层
  • 本章知识点(图片形式)
  • 出现的陌生名词解释

🎉welcome🎉
✒️博主介绍:一名大一的智能制造专业学生,在学习C/C++的路上会越走越远,后面不定期更新有关C/C++语法,数据结构,算法,Linux,ue5使用,制作游戏的心得,和大家一起共同成长。
✈️C++专栏:C++爬塔日记
😘博客制作不易,👍点赞+⭐收藏+➕关注

前情回顾

上回说到,我踏入C++古塔,在第一层中了解到了面向对象的第一大特性——封装,通过努力,我成功获得封装的力量,并且上到了第二层…

对象特性——对象的初始化和清理

踏入第二层当中,那道声音再次飘来:“挑战者,这层的任务需要你掌握对象特性中的初始化和清理,祝你好运…”一块石板再次出现在我的眼前

构造函数和析构函数

什么是构造函数和析构函数

在C++中,对象在被调用和销毁的时候,会默认调用两个函数,在创建对象的时候,会调用构造函数,在销毁的时候会调用析构函数,它们在一个对象中,只会被调用一次,所以构造函数和析构函数是必须存在的,当程序员本身不提供任何的构造和析构函数的时候,编译器会提供默认构造函数

构造函数

构造函数的语法

  • 构造函数没有返回值,也不用写void
  • 构造函数的函数名与类名相同
  • 构造函数可以有参数,可以发生函数重载1

基本语法了解,那构造函数就可以尝试的去写一下。

class A
{
public:
	A()
	{
		cout << "A的构造函数" << endl;
	}
	string a;
};
int main()
{
	A c;
}

在这里插入图片描述

构造函数的分类

按照参数分类

按照参数可以分为:无参构造函数(默认构造函数)和有参构造函数,它们的区别在于函数有无参数。

按照类型分类

按照类型可以分为:普通构造函数和拷贝构造函数。

拷贝构造函数

上面提到了拷贝构造函数,那拷贝构造函数是什么?从表面来看,在构造的同时拷贝,那拷贝什么?数据吗?拷贝到哪里去呢?这里我们先将拷贝构造函数的语法写罗列出来。

  • 类名(const 类名 引用2

可以看到,它的参数是我们的对象,那它的作用大致就可以猜到了,就是将对象的数据拷贝到调用拷贝构造函数的对象上面去,可以用代码来试验一下。

#include<string>
#include<iostream>
using namespace std;

class A
{
public:
	A()
	{
		cout << "A的构造函数" << endl;
	}
	A(A &c)
	{
		b = c.b;
	}
	int b;
};
int main()
{
	A c;
	cin >> c.b;
	A b(c);
	cout<< b.b << endl;
}

在这里插入图片描述
可以看到c里面的内容拷贝到了b里面。

拷贝函数的调用时机

通常在三种情况下调用我们的拷贝函数:

  1. 使用一个已经创建完毕的对象来初始化一个新对象,可以参考上面
  2. 值传递的方式给函数参数传值
  3. 以值的方式返回局部变量

对于第二点,可以看下方这张图来理解在这里插入图片描述
int main函数内部调用test1函数,函数参数为类,在调用函数时候,会调用拷贝构造函数,然后在回去调用test1函数内部。
而第三点,是因为函数中,当返回的值是我们的对象时,因为出了函数体,局部变量销毁,所以函数内对象会进行销毁,这个时候就会发生拷贝,将函数内的对象数据重新拷贝到一块新的空间内,进行返回。

深拷贝和浅拷贝
  • 浅拷贝是进行简单的拷贝操作,只会进行值拷贝
  • 深拷贝是在堆区重新申请空间,进行拷贝

那为什么会出现深拷贝和浅拷贝呢?当类内的属性有指针的时候,这个时候发生拷贝,会拷贝的是地址。
在这里插入图片描述
因为指针内存放数据之前,我们要使用new3函数进行开辟空间,这个时候我们就需要在析构函数内使用delete4释放空间,但是因为两个对象都同时指向了同一块空间,就会释放两个同一块空间的地址,对堆区进行了重复释放,那这个时候想要解决,就需要程序员自己设计出拷贝构造函数,进行深拷贝,对指针的拷贝用new操作符重新开辟一块空间。
深拷贝

class A
{
public:
	A()
	{
		cout << "A的构造函数" << endl;
	}
	//浅拷贝
	A(A &c)
	{
		b=c.b;
		d=c.d;
	}
	//深拷贝
	A(A &c)
	{
		cout << "拷贝构造函数" << endl;
		b = c.b;
		d = new int(*c.d);
	}
	int b;
	int* d;
};

构造函数的调用方法

括号法

括号法在上面我们进行拷贝构造函数调用时已经用过,就是在对象后面加括号,括号内是参数,但是这个时候要注意!对于无参构造函数而言,是在后面加括号的,这样编译器会认为这一个函数声明在这里插入图片描述
在编译器眼中,加括号的就会认为是这样。

显示法

显示法是将我们的构造函数当赋值一样,书写方式如下:

类名 对象名 = 类名(参数);

函数名(参数)叫做匿名对象,特点是当执行结束后,系统会立即回收匿名对象。
注意!:不要利用拷贝构造函数去初始化匿名对象,这个时候编译器会认为这是一个函数声明。

隐式转换法

隐式转换法是将我们的显示法中等号右侧的类名省略,书写方式如下:

类名 对象名 =参数;

构造函数规则

在默认情况下,C++编译器至少会给一个类添加三个函数:

  1. 默认构造函数(无参)(内部空实现)
  2. 默认析构函数(内部空实现)
  3. 默认拷贝构造函数,对属性进行浅拷贝

构造函数规则如下:

如果程序员定义有参构造函数,C++不在提供默认构造函数(无参),但是会提供默认拷贝构造函数,如果程序员定义拷贝构造函数,C++则不会提供任何构造函数。

析构函数

析构函数的语法

  • 没有返回值,也不需要写void
  • 函数名和类名相同,但是需要在名称前加~
  • 析构函数不可以有参数,不能发生重载
class A
{
public:
	A()
	{
		cout << "A的构造函数" << endl;
	}
	//析构函数
	~A()
	{
		
	}
	string a;
};
int main()
{
	A c;
}

析构函数的作用

当类内调用new操作符开辟空间时,需要在析构函数内部进行释放空间的操作,用delete操作符,最好在将指向new操作符开辟的空间的指针,置空,防止野指针。

初始化列表

作用

对类内的属性进行初始化操作

语法

构造函数():属性1(初始值),属性2(初始值)…

class man
{
public:
	//构造函数,初始化列表
	man() :_name("狗蛋"), age(18), car("鬼火")
	{

	}
	
	//属性
	string _name;//名字
	int age;//年龄
	string car;//汽车
};

这是最基础的用法,还可以和有参构造函数进行结合:

#include<string>
#include<iostream>
using namespace std;

class man
{
public:
	//构造函数,初始化列表
	man(string a, int b, string c) :_name(a), age(b), car(c)
	{

	}
	
	//属性
	string _name;//名字
	int age;//年龄
	string car;//汽车
};
int main()
{
	man m1("狗蛋", 18, "鬼火");
	return 0;
}

也可以这样去进行初始化。

类对象作为类成员

在C++中,类中的成员可以是另一个类的对象,这个时候称这个成员为对象成员:

class A
{

};
class B
{
	A a;
};

上述代码中,A a就是对象成员,在我们创建B类的对象时,A a为对象成员,要先有成员才能有这个类,所以会先调用A的构造函数,在调用B的构造函数,但是在解析的时候时相反的,先析构B,在析构A。

静态成员

静态成员变量

静态成员变量,是将我们的成员变量放入到静态区,需要在成员的类型前面加static关键字。

静态成员变量特点

  1. 因为放入到了静态区,所以所有对象是共享同一份数据的,不属于任何的一个对象了
  2. 会在编译阶段就分配内存,相当于在运行之前就已经分配好内存了,分配在全局区
  3. 类内声明,类外初始化,比如有一个初始值才可以用,或者就无法访问到那片内存空间。

对于静态成员变量的初始化我们可以这样:

class A
{
	static int a;
}

int A::a=//初始值;

也是因为上述特点,静态成员不属于任何对象,所有有了两种访问方式:

  1. 通过对象进行访问,访问方式:对象名.成员名
  2. 通过类名进行访问,访问方式:类名:: 成员名

静态成员变量也是遵循访问权限的。

静态成员函数

访问方式

与静态成员变量的访问方式是一样的。

注意事项

  1. 静态成员函数可以访问静态成员变量
  2. 静态成员函数不可以访问非静态的成员变量
  3. 放访问非静态的时候,这个时候静态成员函数是不知道修改的是哪个对象的,如果修改,它会把所有对象的这个属性进行修改

静态成员函数同样遵循访问权限。

掌握对象初始化和清理,步入第三层

随着面前石板的倒下,第三层的楼梯显现在了我的眼前…

本章知识点(图片形式)

在这里插入图片描述

😘预知后事如何,关注新专栏,和我一起征服C++这座巨塔
🚀专栏:C++爬塔日记
🙉都看到这里了,留下你们的👍点赞+⭐收藏+📋评论吧🙉

出现的陌生名词解释


  1. 看到函数重载,可能有些人就懵了,这里解释一下,在C++中,函数名是可以重复的,这个时候参数不同,或者参数的顺序不一样,都是可以的,但是如果光返回类型不同,参数相同,则不能发生函数重载,编译器会报错。 ↩︎

  2. 引用,换一种说法就是取别名,比如,我有一个同学,他叫做李鑫,那我们可能会给他取个外号叫做李三金,当说到这个外号的时候,我们会想到李鑫这个人,所以引用是不会在去内存当中重新开辟一块空间的,它和它引用的变量是用了同一块空间,它的书写形式为:
    数据类型 &变量名=要引用的变量名;
    还要注意,对于引用来说,我们不能对其进行第二次改变,如果aa是a的别名,那aa就不能在改变成别的变量的别名了,对于引用来说,引用就等于我们的指针加const,,把const加在我们的解引用右侧就等于我们的引用。 ↩︎

  3. new操作符是C++用于内存开辟的函数,它的书写形式为:
    指针=new 和指针同类型 (这里可以直接赋值);
    指针=new 和指针同类型 [开辟多少个];
    上面第一种为开辟一个变量空间,第二个为开辟数组空间。 ↩︎

  4. delete操作符,用于对new申请下来的空间进行空间释放,书写形式:
    delete(指针); ↩︎

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DM8:达梦数据库DEM--dmagent监控服务器代理部署(详细步骤)

DM8:达梦数据库DEM部署dmagent代理环境&#xff08;详细步骤&#xff09;1 dmagent代理下载部署1.1通过web DEM下载代理包1.2 从数据库服务器目录直接拷贝dmagent2 部署JDK环境2.1 使用数据库自带的JDK包2.2 配置服务器JDK环境变量3 配置agent.ini文件3.1 103 节点 &#xff0c…

C语言——运算符与表达式

一、赋值运算符 运算符描述实例将右边操作数的值赋给左边操作数AB,即将B的值赋给A加法赋值运算符&#xff0c;将右边操作数加上左边操作数的结果赋值给左边操作数B A 等价于 B B A-减法赋值运算符&#xff0c;将左边操作数减去右边操作数的结果赋值给左边操作数B - A 等价于…

擎创动态 | 酸了酸了,这年会也忒燃了吧

前言&#xff1a;受疫情影响的这一年里&#xff0c;擎创科技逆流勇上&#xff0c;汇聚点点星火&#xff0c;点亮新的征程。擎创的服务随之正式遍及全国&#xff0c;北起重工业基地的东三省&#xff0c;南至改革开放最早的粤港澳大湾区&#xff0c;东起经济中心的大本营上海&…

数据开发面试问题记录

因作者近期正在投递数据开发岗位&#xff0c;所以会在此记录一些面试过程中的问题&#xff0c;持续更新&#xff0c;直到入职新公司为止 1. 数仓建模的三范式理论 所谓的范式&#xff0c;就是我们在关系建模的时候所遵从的一些规范&#xff0c;而三范式&#xff0c;指的就是三…

QML工程之初始工程代码分析

接着上一讲&#xff0c;当建立完工程之后&#xff0c;IDE 会呈现如下的界面下面的代码是main.cpp&#xff0c;工程起始运行的代码段&#xff0c;具体的函数说明都在代码段里面进行了标注。#include <QGuiApplication> //主要是ui进程运行头函数&#xff0c;包含事件循环&…

寻找数组的中心下标

Python-寻找数组的中心下标 题目 给你一个整数数组 nums &#xff0c;请计算数组的 中心下标 。 数组 中心下标 是数组的一个下标&#xff0c;其左侧所有元素相加的和等于右侧所有元素相加的和。 如果中心下标位于数组最左端&#xff0c;那么左侧数之和视为 0 &#xff0c;因…

佳讯频传!安全狗多项能力获信通院认可

近期&#xff0c;信通院发布了其主导的《基于云的工作负载保护平台能力要求》标准以及《零信任产业图谱》。 作为国内云原生安全领导厂商&#xff0c;安全狗也凭借自身综合且突出的安全能力获得信通院认可。 厦门服云信息科技有限公司&#xff08;品牌名&#xff1a;安全狗&a…

【SpringBoot高级篇】SpringBoot集成RocketMQ消息队列]

【SpringBoot高级篇】SpringBoot集成RocketMQ消息队列]RocketMQ简介技术架构基本概念Docker环境安装RocketMQrocketmq-client消息发送基本样例消息发送发送同步消息发送异步消息单向发送消息消费消息负载均衡模式广播模式顺序消息顺序消息生产顺序消费消息延时消息启动消息消费…

基于M实现的JWT解决方案

文章目录基于M实现的JWT解决方案简介现状原理JWT 组成结构头部Header有效载荷Payload哈希签名SignatureJWT完整结果JWT基于M的使用流程总结完整代码基于M实现的JWT解决方案简介JWT 英文名是 Json Web Token &#xff0c;是一种用于通信双方之间传递安全信息的简洁的、URL安全的…

2023年,PMP认证考试的心得分享

对于刚开始要准备参加PMP考试的人&#xff0c;大多应该都是不知道怎么去考试复习好的。PMP认证考试虽是美国的考试&#xff0c;但其实这跟国内其它的考试复习也差不多&#xff0c;没有什么很特别之处&#xff0c;只是多了一个中英互译&#xff0c;再就是学习的内容不一样&#…

windows系统中环境系统变量和用户变量的区别

前言 -- 什么是环境变量一般我们安装软件之后&#xff0c;为了能够在cmd命令行运行软件&#xff0c;一般都需要设置一下环境变量&#xff0c;否则就会出现找不相关命令的错误提示。所谓环境变量&#xff0c;可以简单理解为就是给操作系统定义的一些路径和名称。比如使用最常使用…

个人对粗糙集的一些理解和简单举例

文章目录1、 数据价值密度低的解决方案1.1 粗糙集中对应的概念&#xff1a;属性约简1.2 属性约简的好处1.3 粗糙集的应用2、粗糙集的简介--->原理2.1 粗糙集的概念2.2 从例子看粗糙集2.3 粗糙集模型的分类及其评估标准3、粗糙集的主要研究方向3.1 模型创新3.2 属性约简3.3 提…

浅析正则表达式+范围规则校验表达式+js从字符串中截取数字

平时项目中经常需要用到正则表达式&#xff0c;可惜之前太懒(当然最主要是太菜也不会写)都是直接网上搜。之前用的也简单&#xff0c;无非是校验手机号码格式、校验邮箱格式、偶尔有校验密码这种&#xff0c;网上一搜一大堆&#xff0c;根本不用自己写&#xff0c;结果前段时间…

【ONE·C || 函数与数组】

总言 C语言&#xff1a;函数、数组初步认识。 文章目录总言1、函数1.1、是什么1.1.1、基本介绍1.1.2、库函数使用演示(strcpy、memset)1.1.3、自定义函数使用演示1.2、函数参数、传值调用和传址调用1.3、相关练习1.3.1、写一个函数&#xff1a;可以判断一个数是不是素数1.3.2、…

集成学习-理论概述

1、集成学习概述集成学习(ensemble learning)本身不是一个单独的机器学习算法&#xff0c;而是通过构建并结合多个机器学习器来完成学习任务。集成学习的特点&#xff1a;集成方法是一种将几种机器学习技术组合成一个预测模型的元算法&#xff0c;以减小方差&#xff08;baggin…

python-文件和异常

1. 从文件中读取数据1.1. 读取整个文件在同目录下创建textA文本文件123 456 789a. open函数&#xff1a;要以任何方式去使用文件&#xff0c;都需要先打开文件&#xff0c;它接受一个参数——要打开文件的名称。 open()返回一个表示文件的对象。b. 关键字with在不再需要访问文件…

可以自动生成日报的清单工具

用过了很多todolist工具&#xff08;Microsoft_ _To D、oodoist、滴答清单、印象笔记、有道笔记、&#xff09; 最终稳定一直在用的就这一个“闪点清单” 我的核心诉求就两点 1. 可以实时记录任务&#xff0c;并标记是否完成 2. 可以按天、周导出&#xff0c;自动整合成日报…

《计算机构造与解释》读书笔记(4)

文章目录1. 写在最前面2. 并发&#xff1a;时间是一个本质问题2.1 并发系统中时间的性质2.1.1 并发程序的正确行为2.2 控制并发的机制2.2.1 对共享变量的串行访问2.2.2 Schema 里的串行化2.2.3 使用多重共享资源的复杂性2.2.4 串行化实现2.2.5 死锁2.2.6 并发性、时间和通信3. …

Linux学习记录——구 进程概念的基础理解

文章目录一、操作系统概念理解二、进程的基本理解1、什么是进程&#xff1f;2、进程的属性1、指令查看进程2、目录查看进程3、进程与进程之间1、父子进程概念2、创建子进程---fork的基础使用方法3、fork原理的初级理解1、fork的操作2、fork如何看待代码和数据3、fork如何看待两…

【Docker概念和实践 2】虚拟机 ubuntu18上安装docker

一、说明 已经安装了N遍Docker了&#xff0c;逐步成了一套习惯&#xff0c;这里专门记录之&#xff1b;总之&#xff0c;安装前必须回答得问题是&#xff1a;何种操作系统、何种版本、是否虚拟机、云数据源等问题。一个环境如果装得好&#xff0c;就不需要重装&#xff0c;如果…