首页 > 其他分享 >2.2对象的初始化和清理

2.2对象的初始化和清理

时间:2024-03-17 21:36:10浏览次数:23  
标签:初始化 函数 对象 成员 清理 Person 2.2 拷贝 构造函数

1、生活中我们买电子产品都基本会有出厂设置,在某一天我们不用的时候也会删除一些自己信息数据来保证安全。
2、C++中的面向对象来源于生活,每个对象也都会有初始设置以及对象销毁前的清理数据的设置。

1、构造函数和析构函数

对象的初始化清理也是两个非常重要的安全问题。

一个对象或者变量没有初始状态,对其使用后果是未知的。
同样的使用完一个对象或变量,没有及时清理,也会造成一定的安全问题。

C++利用构造函数析构函数解决上述问题,这两个函数将会被编译器自动调用,完成对象初始化和清理工作。
对象的初始化和清理工作是编译器强制要我们做的事情,因此如果我们不提供构造和析构,编译器会提供
编译器提供的构造函数和析构函数是空实现

1、构造函数(constructor)

主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。
主要任务是初始化类对象的数据成员,无论何时只要类的对象被创建,就会执行构造函数。

类可以包含多个构造函数,和其他重载函数差不多,不同的构造函数之间必须在参数数量或参数类型上有所区别。

构造函数不能被声明为const,

构造函数语法:类名(){}
1.构造函数,没有返回值也不写void。
2.函数名称与类名相同。
3.构造函数可以有参数,因此可以发生重载。
4.程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次。

2、析构函数

主要作用在于对象销毁前系统自动调用,执行一些清理工作。

析构函数语法:~类名(){}
1.析构函数,没有返回值也不写void。
2.函数名称与类名相同,在名称前加上符号“~”。
3.析构函数不可以有参数,因此不可以发生重载。
4.程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次。

2、构造函数的分类及调用

分类:

按参数分为:有参构造和无参构造
按类型分为:普通构造和拷贝构造

//无参构造函数
Person(){ }
//有参构造函数
Person(int a){
	age = a;
}
//拷贝构造函数  需要用const修饰,还要加&, 不能拷贝的同时还修改它
Person( const Person &p){
	age = p.age; //将传入的人身上的所有属性,拷贝到我身上
}

调用:

三种调用方式:
括号法

Person p1; //默认构造函数调用
Person p2(10); //有参构造函数
Person p3(p2); //拷贝构造函数

注意:调用默认构造函数的时候,不要加()
因为这样写,编译器会认为是Person p1();一个函数的声明,不会认为是在创建对象。

显示法

Person p1;
Person p2 = Person(10); //有参构造
Person p3 = Person(p2); //拷贝构造

Person(10); //是一个匿名对象,在当前执行结束后,系统会立即回收掉匿名对象。

注意:不要利用拷贝构造函数初始化匿名对象,编译器会认为Person(p3)等价于Person p3; 认为这是一个对象的声明。会引发重定义错误。

隐式转换法

Person p4 = 10; //相当于 写了 Person p4 = Person(10); 有参构造
Person p5 = p4; //拷贝构造

3、拷贝构造函数调用时机

C++中拷贝构造函数调用时机通常用三种情况

1.使用一个已经创建完毕的对象来初始化一个新对象。

如:先创建好p1,然后将p1的属性拷贝给p2。

void test01()
{
	//括号法创建对象
	Person p1(20);
	Person p2(p1); //将p1的属性拷贝给p2
	cout << "p2的年龄" << p2.m_Age << endl;
}

2.值传递的方式给函数参数传值。

void doWork( Person p )
{
	p.m_Age = 100;  //这里的赋值操作,并不会更改原始的p的年龄,
}

void test02()
{
	Person p; 	//调用默认构造
	p.m_Age = 10;
	cout << "p的年龄是:" << p.m_Age << endl;  	//输出结构为10
	doWork(p); 	//调用这个函数时,用值传递的方式拷贝一个临时的副本,并不会影响原始的数据。
	cout << "p的年龄是:" << p.m_Age << endl;	//输出结果为10,不变
}

3.以值方式返回局部对象。

(暂时听不懂)

4、构造函数调用规则

默认情况下,C++编译器至少给一个类添加3个函数
1.默认构造函数(无参,函数体为空)

2.默认析构函数(无参,函数体为空)

3.默认拷贝函数,对属性进行拷贝

构造函数调用规则如下:
1.如果用户定义有参构造函数,C++不再提供默认无参构造函数,但是会提供默认拷贝构造函数。
2.如果用户定义拷贝函数,C++不会再提供其他构造函数。

5、深拷贝与浅拷贝

深浅拷贝是面试经典问题,也是常见的一个坑

浅拷贝:简单的赋值拷贝操作

深拷贝:在堆区重新申请空间,进行拷贝操作

浅拷贝带来的问题就是堆区的内存重复释放,这个问题要利用深拷贝来解决
自己实现拷贝构造函数,解决浅拷贝带来的问题。
深拷贝是:p1指向一块堆区,p2也指向一块堆区,p1和p2的数据是一样的。在释放的时候,p1,p2释放各自的堆区,两个堆区不会重复释放,

m_Height = p.m_Height; //编译器默认实现就是这行代码
m_Height = new int(*p.m_Height); //深拷贝操作

如果我们在堆区开辟了一块内存,这个时候,你需要用析构函数,在堆区把它的内存释放干净。

6、初始化列表

C++提供了初始化列表语法,用来初始化属性
语法:构造函数(): 属性1(值1), 属性2(值2)...{}

传统的初始化操作

Person(int a, int b, int c)
{
	m_A = a;
	m_b = b;
	m_C = c;
}
Person p (10,20,30);

//初始化列表操作
Person(): m_A(10), m_B(20), m_C(30)
{
}
Person p(); //调用
//但是这样就只能赋值10,20,30,如何更灵活的去赋值?

Person(int a, int b, int c): m_A(a), m_B(b), m_C(c)
{
}
Person p(30,20,10); //调用

7、类对象作为成员

C++类中的成员可以是另一个类的对象,我们称该成员为 对象成员
例如:

class A{}
class B
{
	A a;
}

B类中有对象A作为成员,A为对象成员
那么当创建B对象时,A与B的构造和析构的顺序时谁先谁后?

构造顺序:先构造A,再构造B。
当其他类对象作为本类成员,构造时先构造其他类对象,再构造自身!(先构造零件,再构造本体)

析构顺序:先构造B,再构造A
析构顺序和构造顺序相反

8、静态成员

静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员。

静态成员分为:

1.静态成员变量

   所有对象共享同一份数据
   在编译阶段分配内存
   类内声明,类外初始化   //这个类必须有一个初始化的值

创建静态成员变量:

class Person
{
public:
	statci int m_A;  //类内声明
};
int Person::m_A = 100; //类外初始化 注意格式!

静态成员变量 不属于某个对象,所有对象都共享同一份数据
因此,静态成员变量有两种访问方式:
1.通过对象进行访问

Person p; //创建对象
cout << p.m_A << endl;  //输出对象的属性(访问对象)

2.通过类名进行访问
cout << Person::m_A << endl;

静态成员变量也是有访问权限的。
如:private的静态变量,只能在类内进行访问

2.静态成员函数

   所有对象共享同一个函数
   静态成员函数只能访问静态成员变量

创建静态成员函数:

class Person 
{
public:
	static void func()
	{
		cout << "static void func 调用 " << endl;
	}
}

两种访问方式:
1.通过对象访问

Person p;
p.func();

2.通过类名访问
Person::func();

静态成员函数只能访问静态成员变量

static void func()
{
	m_A = 100; //可以正确访问
	m_B = 200; //会报错,静态成员函数不可以访问非静态成员变量,编译器无法区分到底是哪个对象的m_B属性
}

static int m_A; //静态成员变量
int m_B; //非静态成员变量

静态成员函数也是有访问权限的。
如:类外访问不到私有静态成员函数

标签:初始化,函数,对象,成员,清理,Person,2.2,拷贝,构造函数
From: https://www.cnblogs.com/H43724334/p/18078557

相关文章

  • Linux:系统初始化,内核优化,性能优化(1)
    我们安装好了一个服务器之后,一定要对他的系统,内核,性能一系列进行一个优化,否则当大并发的情况下很可能出现问题,我把要优化的东西直接罗列出来并介绍,后期可以直接编写一个脚本拿到服务器上直接用就行        设置时区我们在中国,一般选择的都是亚洲上海,在装服务器的时......
  • Java创建数组、赋值的四种方式,声明+创建+初始化 详解
    @目录一、创建数组的四种方式二、详解三、数组存储的弊端一、创建数组的四种方式以int数据类型为例@TestpublicvoidtestNewArray(){//创建数组//法一int[]arr1=newint[]{1,2,3,4,5};System.out.println(arr1.length+""+arr1[2]);//5......
  • 沃伦·巴菲特2023股东书(2024.2.24)-0-查理·芒格——伯克希尔·哈撒韦公司的建筑师
    2023letterhttps://www.berkshirehathaway.com/letters/2023ltr.pdf查理·芒格——伯克希尔·哈撒韦公司的建筑师查理·芒格于11月28日去世,距离他100岁生日仅33天。虽然在奥马哈出生和长大,但他一生中80%的时间都在其他地方定居。因此,直到1959年他35岁时,我才第一次......
  • Spring 5.x 源码之旅-59AOP事务的初始化流程一
    作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬学习必须往深处挖,挖的越深,基础越扎实!阶段1、深入多线程阶段2、深入多线程设计模式阶段3、深入juc源码解析阶段4、深入jdk其余源码解析......
  • Spring 5.x 源码之旅-59AOP事务的初始化流程二
    作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬学习必须往深处挖,挖的越深,基础越扎实!阶段1、深入多线程阶段2、深入多线程设计模式阶段3、深入juc源码解析阶段4、深入jdk其余源码解析......
  • gnupg2 2.2.20版本,命令参数说明
    gpg(GnuPG)2.2.20libgcrypt1.8.5Copyright(C)2020FreeSoftwareFoundation,Inc.LicenseGPLv3+:GNUGPLversion3orlater<https://gnu.org/licenses/gpl.html>Thisisfreesoftware:youarefreetochangeandredistributeit.ThereisNOWARRAN......
  • Elasticsearch - Docker安装Elasticsearch8.12.2
    前言最近在学习ES,所以需要在服务器上装一个单节点的ES服务器环境:centos7.9安装下载镜像目前最新版本是8.12.2dockerpulldocker.elastic.co/elasticsearch/elasticsearch:8.12.2创建配置新增配置文件elasticsearch.ymlhttp.host:0.0.0.0http.cors.enabled:true......
  • fastjson1.2.24-RCE漏洞复现
    触发过程图靶场模拟1、实验环境准备攻击者kali(192.168.101.141)使用工具:marshalsec-0.0.3-SNAPSHOT-all.jarGitHub-RandomRobbieBF/marshalsec-jar:marshalsec-0.0.3-SNAPSHOT-allcompiledonX64被攻击者centos7(192.168.101.148)使用工具:dockerdocker-compose......
  • day4数据清理以及特征提取
    第一步:导入ps:最后一行是为了查看是否成功导入缺失值处理df.info()df.isnull().sum() df.info是一个用于查看DataFrame的基本信息的函数。它可以帮助我们了解DataFrame的列名、非空值数量、数据类型等信息。df.isnull().sum()是一个用于计算DataFrame中每列空......
  • KubeSphere 社区双周报|2024.02.29-03.14
    KubeSphere社区双周报主要整理展示新增的贡献者名单和证书、新增的讲师证书以及两周内提交过commit的贡献者,并对近期重要的PR进行解析,同时还包含了线上/线下活动和布道推广等一系列社区动态。本次双周报涵盖时间为:2024.02.29-03.14。贡献者名单新晋KubeSpherecontribu......