C++核心编程——4.2(2)对象的初始化和清理

news2024/11/18 14:49:44

4.2.5 深拷贝与浅拷贝

浅拷贝:编译器提供的简单的赋值拷贝操作

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

示例:

class Person {
public:
	//无参(默认)构造函数
	Person() {
		cout << "无参构造函数!" << endl;
	}
	//有参构造函数
	Person(int age ,int height) {
		
		cout << "有参构造函数!" << endl;

		m_age = age;
		m_height = new int(height); //利用关键字new把身高放在堆区,返回的是一个地址
		
	}
	//拷贝构造函数  
	Person(const Person& p) {
		cout << "拷贝构造函数!" << endl;
		//如果不利用深拷贝在堆区创建新内存,会导致浅拷贝带来的重复释放堆区问题
        //自己写一个拷贝构造函数,解决浅拷贝带来的问题:在堆区再开辟一段空间
		m_age = p.m_age;
        //m_height = p.m_height (编译器自动提供时的拷贝构造函数写法)
		m_height = new int(*p.m_height);   //深拷贝重新开辟一块内存
		      //通过传入的地址进行解引用之后,再在堆区申请一块内存存入
	}

	//析构函数
	~Person() {
//析构代码,将堆区开辟的数据做释放操作(堆区的数据需要程序员手动开辟,也需要程序员手动释放)
//在对象销毁前对堆区的数据释放掉(test01执行完了之后),所以在析构函数时把数据释放干净
		cout << "析构函数!" << endl;
		if (m_height != NULL)   //如果该指针不为空,就将其用delete删除
		{
			delete m_height;
            m_height = NULL;   //防止野指针出现,将其置空
		}
	}
public:
	int m_age;
	int* m_height;      //用指针是为了把数据开辟到堆区
};

void test01()
{
	Person p1(18, 180);

	Person p2(p1);  //当我们不提供拷贝构造函数数,编译器自动帮我们提供,并且做浅拷贝

	cout << "p1的年龄: " << p1.m_age << " 身高: " << *p1.m_height << endl;

	cout << "p2的年龄: " << p2.m_age << " 身高: " << *p2.m_height << endl;
}

int main() {

	test01();

	system("pause");

	return 0;
}

具体差别如下图所示:

 总结:如果属性有在堆区开辟的,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题

4.2.6 初始化列表

作用:

C++提供了初始化列表语法,为类中的属性进行初始化(类似于构造函数的初始化)

语法:构造函数():属性1(值1),属性2(值2)... {}

示例:

class Person {
public:

	传统方式初始化,创建对象同时赋值
	//Person(int a, int b, int c) {
	//	m_A = a;
	//	m_B = b;
	//	m_C = c;
	//}

	//初始化列表方式初始化
	Person(int a, int b, int c) :m_A(a), m_B(b), m_C(c) {}
	// 写法2:Person() :m_A(1), m_B(2), m_C(3) {}  但是值被固定,不够灵活
    void PrintPerson() {
		cout << "mA:" << m_A << endl;
		cout << "mB:" << m_B << endl;
		cout << "mC:" << m_C << endl;
	}
private:
	int m_A;
	int m_B;
	int m_C;
};

int main() {

	Person p(1, 2, 3);
    //对应类中的写法2:Person p; 
	p.PrintPerson();

	system("pause");
	return 0;
}

4.2.7 类对象作为类成员

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

构造函数:先构造类中的成员(调用类中成员的构造),再构造本类

析构函数:与构造顺序相反

例如:

class A {}
class B
{
    A a;
}

 示例:

class Phone
{
public:
	Phone(string name)
	{
		m_PhoneName = name;
		cout << "Phone构造" << endl;
	}

	~Phone()
	{
		cout << "Phone析构" << endl;
	}

	string m_PhoneName;

};


class Person
{
public:

	//初始化列表可以告诉编译器调用哪一个构造函数
    //相当于 Phone m_Phone = pName 隐式转换法用pName创建对象
	Person(string name, string pName) :m_Name(name), m_Phone(pName)
	{                                
		cout << "Person构造" << endl;
	}

	~Person()
	{
		cout << "Person析构" << endl;
	}
	
	string m_Name;
	Phone m_Phone;

};
void test01()
{
	//当类中成员是其他类对象时,我们称该成员为 对象成员
	//构造的顺序是 :先调用对象成员的构造,再调用本类构造
	//析构顺序与构造相反
	Person p("张三" , "华为mate60 Pro");
	cout << p.m_Name << " 使用" << p.m_Phone.m_PhoneName << " 手机! " << endl;

}


int main() {

	test01();

	system("pause");
	return 0;
}

4.2.8 静态成员

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

静态成员变量静态成员函数
特点
  • 所有对象共享同一份数据 (不属于任何一个对象上的)

(在内存中只有一个值,其他函数修改之后再调用也会变成修改后的值)

  • (程序还没有运行)在编译阶段分配内存

  • 类内声明,类外初始化(必须初始化否则无法使用)

  • 也是有访问权限的区别的

  • 所有对象共享同一个函数(同静态成员变量)

  • 静态成员函数只能访问静态成员变量(无法访问非静态成员变量)

  • 也有访问权限

调用方式(静态成员函数的调用要增加作用域)
  1. 通过对象进行访问(像之前一样正常通过 类名.变量名 进行访问)

  2. 通过类名进行访问(直接用变量的名字进行访问)

示例1 :静态成员变量

class Person
{
	
public:

	static int m_A; //静态成员变量(类内声明)

private:
	static int m_B; //静态成员变量也是有访问权限的
};
int Person::m_A = 10;   //类外初始化(为了说明是Person下的要写作用域Person::)
int Person::m_B = 10;

void test01()
{
	//静态成员变量两种访问方式

	//1、通过对象
	Person p1;
	p1.m_A = 100;
	cout << "p1.m_A = " << p1.m_A << endl;

	Person p2;
	p2.m_A = 200;           //用p2去修改m_A的值
	cout << "p1.m_A = " << p1.m_A << endl; //共享同一份数据
	cout << "p2.m_A = " << p2.m_A << endl;

	//2、通过类名
	cout << "m_A = " << Person::m_A << endl;


	//cout << "m_B = " << Person::m_B << endl; //私有权限访问不到
}

int main() {

	test01();

	system("pause");
	return 0;
}

示例2:静态成员函数

class Person
{

public:
	
	static void func()             //静态成员函数
	{
		cout << "func调用" << endl;
		m_A = 100;    //只能访问静态成员变量
		//m_B = 100; //错误,不可以访问非静态成员变量
        //非静态成员变量必须通过创建对象才能够调用,当调用静态成员函数(程序中只有一份值)不知道改变的是哪一个对象上面的非静态成员变量(无法区分)
	}

	static int m_A; //静态成员变量(类内声明)
	int m_B;       // 非静态成员变量
private:

	//静态成员函数也是有访问权限的
	static void func2()
	{
		cout << "func2调用" << endl;
	}
};
int Person::m_A = 10;  //(类外初始化)


void test01()
{
	//静态成员变量两种访问方式

	//1、通过对象
	Person p1;
	p1.func();

	//2、通过类名
	Person::func();    //不用对象直接通过类名进行调用(但是要写明作用域)


	//Person::func2(); //私有权限访问不到
}

int main() {

	test01();

	system("pause");
	return 0;
}

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

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

相关文章

并发编程之线程池的应用以及一些小细节的详细解析

线程池在实际中的使用 实际开发中&#xff0c;最常用主要还是利用ThreadPoolExecutor自定义线程池&#xff0c;可以给出一些关键的参数来自定义。 在下面的代码中可以看到&#xff0c;该线程池的最大并行线程数是5&#xff0c;线程等候区&#xff08;阻塞队列)是3&#xff0c;即…

基于Python的微博旅游情感分析、微博舆论可视化系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

JAVAEE之Cookie/Session

1.Cookie HTTP 协议自身是属于 "无状态" 协议. "无状态" 的含义指的是: 默认情况下 HTTP 协议的客户端和服务器之间的这次通信, 和下次通信之间没有直接的联系. 但是实际开发中, 我们很多时候是需要知道请求之间的关联关系的. 例如登陆网站成功后, 第二…

绩效考核存在合理性、公平性、客观性吗?

目录 一、绩效考核流于形式&#xff1a;没有实际考核过 二、考核结果的确定: 主管一人说了算 三、考核结果&#xff1a; 与绩效奖金挂钩吗&#xff1f; 四、考核的滥用&#xff1a;成为公司排挤迫使员工离职的手段 五、公司说&#xff1a; 让你滚蛋&#xff0c;谁还会发你奖…

[HackMyVM]靶场Boxing

难度:Medium kali:192.168.56.104 靶机:192.168.56.143 端口扫描 ┌──(root㉿kali2)-[~/Desktop] └─# nmap 192.168.56.143 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-04-03 19:25 CST Nmap scan report for staging-env.boxing.hmv (192.168.56.143) Host …

智慧展览馆:基于AI智能识别技术的视频智慧监管解决方案

一、建设背景 随着科技的不断进步和社会安全需求的日益增长&#xff0c;展览馆作为展示文化、艺术和科技成果的重要场所&#xff0c;其安全监控系统的智能化升级已成为当务之急。为此&#xff0c;旭帆科技&#xff08;TSINGSEE青犀&#xff09;基于视频智能分析技术推出了展览馆…

路径规划——曲线拟合详解(一):多项式轨迹与QP优化(minimum-snap算法核心部分)

前言 历经一个多星期时间&#xff0c;我们在路径规划——搜索算法部分讲解了7种常见的路径搜索算法&#xff0c;每一种算法的链接放在下面了&#xff0c;有需要的朋友点击跳转即可&#xff1a; 路径规划——搜索算法详解&#xff08;一&#xff09;&#xff1a;Dijkstra算法详…

redis之穿透、击穿、雪崩

目录 缓存雪崩 问题描述 缓存雪崩 问题描述 key 对应的数据存在&#xff0c;但在 redis 中过期&#xff0c;此时若有大量并发请求过来&#xff0c;这些请求发现缓存过期一般都会从后端数据库加载数据并回设到缓存&#xff0c;这个时候大并发的请求可能会瞬间把后端数据库压垮。…

GPTfinger赋能指纹识别技术,德施曼赢下这一局

生成式AI这场战局里&#xff0c;德施曼跑赢同行&#xff0c;成为行业里第一个引入GPT技术的智能锁厂商。 4月2日&#xff0c;德施曼智能锁在北京举办了新品发布会之前的“创新技术预沟通会”&#xff0c;向到场媒体揭晓了最新技术突破之一——GPTfinger。 「智哪儿」认为&…

关闭PyCharm中因双击Shift而跳出的搜索框

有时候老是多次按到shift而跳出一个搜索框&#xff0c;本来在编写代码&#xff0c;怎么突然就开始搜索了&#xff0c;非常的烦人。 其实这个搜索框叫做“随处搜索”。 关闭步骤 1、打开PyCharm的设置。 2、在设置-高级设置中勾选-禁用双击修改键快捷键即可。

4.3学习总结

[HNCTF 2022 WEEK2]Canyource&#xff08;无参数&#xff09; 通过这题又接触了一种无参数RCE的方法&#xff0c;前面学习的getallheaders只有在apache环境下才能使用&#xff0c;具有一定的局限性 这里是利用php函数来构造读取flag的方法 localeconv() – 函数返回一个包含本…

Ribbon有哪些负载均衡策略

负载均衡类都实现了IRule接口。 RandomRule&#xff1a;随机的选用一个实例 RoundRobinRule&#xff1a;轮询的使用实例 RetryRule&#xff1a;在轮询的基础上加了一个错误重试机制&#xff0c;在deadline时间内会不断的重试 WeightResponeTimeRule&#xff1a;根据权重去做…

Golang 开发实战day07 - Functions

Golang 教程07 - Functions 1. Functions 1.1 什么是函数&#xff1f; 在 Golang 中&#xff0c;函数就像是代码的超级组合体&#xff0c;可以将一段代码封装成一个独立的单元&#xff0c;以便重复使用。 1.2 函数声明 func funcName(parameter1 type1, parameter2 type2)…

必看!香港Web3活动周跑会指南

星移斗转&#xff0c;又是一年嘉年华。 去年4月&#xff0c;在《虚拟资产发展政策宣言》的影响下&#xff0c;四散的华人Web3生态再度汇集&#xff0c;由万向区块链实验室、HashKey Group、W3ME联合举办的Hong Kong Web3 Festival 2023率先奏响了以香港为鼓点的加密奏曲&#x…

Celery的任务流

Celery的任务流 在之前调用任务的时候只是使用delay()和apply_async()方法。但是有时我们并不想简单的执行单个异步任务&#xff0c;比如说需要将某个异步任务的结果作为另一个异步任务的参数或者需要将多个异步任务并行执行&#xff0c;返回一组返回值&#xff0c;为了实现此…

个人医疗开支预测项目

注意&#xff1a;本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 &#xff08;[www.aideeplearning.cn]&#xff09; 项目背景 随着医疗成本的持续上涨&#xff0c;个人医疗开支成为一个重要议题。理解影响医疗费用的多种因素对于医疗保险公司、政府机构以及个人…

计算机组成结构1

概念 计算机组成&#xff1a; 运算器、控制器、存储器、输出设备、输入设备 CPU&#xff1a;运算器控制器 运算器&#xff1a;算数逻辑单元ALU、累加寄存器AC、数据缓冲寄存器DR、状态条件寄存器PSW 控制器&#xff1a;指令寄存器IR、程序计数器PC、地址寄存器AR、指令译码器I…

制作ubuntu镜像及烧录

最近更换了nuc主机作为机器人的控制主机&#xff0c;为了避免之前在操作系统过程中把系统搞崩了的惨状决定养成定期备份系统的好习惯&#xff0c;这就需要掌握制作系统镜像及烧录的能力。 1、安装systemback软件 ubuntu中可以使用systemback工具进行系统的备份&#xff0c;这…

人工智能、深度伪造和数字身份:企业网络安全的新前沿

深度伪造&#xff08;Deepfakes&#xff09;的出现打响了网络安全军备竞赛的发令枪。对其影响的偏执已经波及到一系列领域&#xff0c;包括政治错误信息、假新闻和社交媒体操纵。 深度伪造将加剧公共领域对信任和沟通的本已严峻的压力。这将理所当然地引起监管机构和政策制定者…

鸿蒙南向开发实战:【智能窗帘】

样例简介 智能窗帘设备不仅接收数字管家应用下发的指令来控制窗帘开启的时间&#xff0c;而且还可以加入到数字管家的日程管理中。通过日程可以设定窗帘开关的时间段&#xff0c;使其在特定的时间段内&#xff0c;窗帘自动打开或者关闭&#xff1b;通过日程管家还可以实现窗帘…