20240416,深拷贝浅拷贝,对象初始化和清理,对象模型和THIS指针

 哈哈哈乌龟越狱了

目录

2.5 深拷贝&浅拷贝

2.6 初始化列表

2.7 类对象作为类成员

2.8 静态成员

2.9 成员变量和成员函数分开存储

2.10 THIS指针的用途

2.11 空指针访问成员函数

2.12 COSNT修饰成员函数

2.5 深拷贝&浅拷贝

浅拷贝:简单的赋值拷贝炒作
深拷贝:在堆区重新申请空间进行拷贝操作

浅拷贝带来的问题就是堆区的内存重复释放;深拷贝是?拷贝的时候重新申请一块内存,记录的数据是一样的,指向的内存是不一样的?

20240411,内存分区模型,new-delete语句-CSDN博客(一些根本不复习学了就忘还找不到笔记人士,乐,还好学的不多?/不是)

如果属性在堆区开辟的,一定要自己构造深拷贝函数避免出现问题

#include<iostream>
using namespace std;
class Person
{
public:
	int m_age;
	int* m_height;//指针接收
	Person()
	{
		cout << "Persong 默认构造 函数的调用" << endl;
	}
	Person(int age,int height)
	{
		m_age = age;
		m_height=new int(height);//把身高创建在堆区,new返回的是该数据类型的指针
		cout << "Persong 有参构造 函数的调用" << endl;
	}
	//系统提供的拷贝函数是浅拷贝
	//自己写一个深拷贝构造函数,解决深拷贝带来的问题
	Person(const Person &p)
	{
		m_age = p.m_age;
		//m_height = p.m_height;编译器写的
		m_height = new int(*p.m_height);
		//在堆区申请一块区域,记录*p_height的内容,即,在堆区创建数据*p_hright
		//此时new int(height)没有释放
		cout << "Persong 拷贝构造 函数的调用" << endl;
	}
	~Person()
	{
		if (m_height != NULL)
		{
			delete m_height;//释放
			m_height = NULL;//初始化
		}
		cout << "Persong 默认析构 函数的调用" << endl;//将堆区开辟的数据做释放操作
	}
};
void test01()
{
	Person p1(28,180);//执行了一次析构函数,指针指向的内存已经被释放掉了
	cout << "p1的年龄为" << p1.m_age <<"身高为"<<*p1.m_height << endl;
	Person p2(p1);
	//拷贝了m_height记录的地址,此时m_height不为空,
	//但是地址指向的地方已经被释放了,再进行一次释放,非法操作
	cout << "p2的年龄为" << p2.m_age << "身高为" << *p2.m_height << endl;
	//函数结束一起释放
}
int main()
{
	test01();
	system("pause");
	return 0;
}
2.6 初始化列表

构造函数():属性1(值 1),属性2(值2)···{ }
构造函数(int a ,int b ,```):属性1(a),属性2(b)···{ }

#include<iostream>
using namespace std;
class Person
{
public:
	int m_a;
	int m_b;
	int m_c;
	Person () :m_a(10), m_b(20), m_c(30) {}//不能修改数值
	Person(int a, int b, int c) :m_a(a),m_b(b),m_c(c){}//可以修改
};
void test01()
{
	Person p;
	Person p1(540, 23, 45);//int a=540,m_a(a)
	cout << p.m_a << "\t" << p.m_b << "\t" << p.m_c << endl;
	cout << p1.m_a << "\t" << p1.m_b << "\t" << p1.m_c << endl;
}
int main()
{
	test01();
	system("pause");
	return 0;
}
2.7 类对象作为类成员

俺的BUG:没有特意创建一个子对象,无法输出被嵌套的子对象
构造和析构的顺序相反

#include<iostream>
#include<string>
using namespace std;
class Phone
{
public:
	string m_Pname;
	Phone(string Pname)
	{
		m_Pname = Pname;
		cout << "Phone的 构造函数  调用" << endl;
	}
	~Phone()
	{
		cout << "Phone的 析构函数  调用" << endl;
	}
};
class Person
{
public:
	string m_Name;
	Phone m_Phone;
	Person(string name, string phone) :m_Name(name), m_Phone(phone) 
	{
		cout << "Person的 构造函数  调用" << endl;
	}
	~Person()
	{
		cout << "Person的 析构函数  调用" << endl;
	}//先释放PERSON的,再释放PHONE的
};
void test01()
{
	Person p("张三", "华为p60");
	cout << p.m_Name  << endl;//先构造了一个Phone类,先调用了PHONE的构造函数,再PERSON的构造函数
	//cout << p.m_Name << "拿了" << p.m_Phone << endl;//编译错误
	//说没有 操作数 能匹配<<的运算符
}
int main()
{
	test01();
	system("pause");
	return 0;
}
2.8 静态成员

静态成员变量:所有对象共享同一份数据,编译阶段分配内存,类内声明,类外初始化
静态成员函数:所有对象共享同一个函数,静态成员函数只能访问静态成员变量

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

class Person
{
public:
	//(全局?共享),编译分配,类内声明&类外初始化(否则无法访问)
	static int m_a;
	int m_c;
	static void func()
	{
		m_a = 999;
		//m_c = 888;//静态成员函数只能访问静态成员变量   因为所有对象共享,无法区分m_c属于哪一个对象?
		cout << "静态成员函数  func() 的调用" << endl;
	}
private:
	//静态成员变量,函数 也有访问权限
	static int m_b;
	static void func2()
	{
		cout << "private 静态成员函数  func() 的调用" << endl;
	}
};
//类外初始化,初始化了之后,没有修改的情况下,就是100
int Person::m_a = 100;
int Person::m_b = 300;

void test01()
{
	Person p;
	cout << p.m_a << endl;//无法解析的外部符号
	Person p2;
	cout << p2.m_a << endl;//通过对象访问
	p2.m_a = 200;
	cout << p2.m_a << endl;
	cout << p.m_a << endl;//输出200,P和P1共享这一个静态变量
}
void test02()
{
	//静态成员变量,不属于某个对象上,所有对象共享同一份数据
	//两种访问方式:通过对象,通过类名
	cout << Person::m_a << endl;
	//cout << Person::m_b << endl;//m_b是私有作用域,不能类外访问
}
void test03()
{
	//静态成员函数访问:对象,类名
	Person::func();
	Person p,p1;
	p.func();
	p1.func();
	//Person::func2();无权限
}
int main()
{
	test02();//输出100
	cout << endl;
	test01();
	cout << endl;
	test02();//输出200,
	cout << endl;
	test03();
	test02();
	system("pause");
	return 0;
}
2.9 成员变量和成员函数分开存储

只有非静态的变量才在对象上

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

class Person
{

};
class Pers
{
	int m_a;
	int m_b;
	static int m_c;//不属于类的对象上
	void func(){}//也
	static void func2(){}//也
};
int Pers::m_c = 800;
void test01()
{
	Person p;
	cout << "size of Person p=" << sizeof(p) << endl;
	//空对象占用内存 1
	//C++编译器会给每个空对象也分配一个字节空间,是为了区分空对象占内存的位置
	//(区分不同的空对象)每个空对象也应该有一个独一无二的内存地址
}
void test02()
{
	Pers p;
	cout << "size of Pers p=\t" << sizeof(p) << endl;//内存对齐成员变量
}
int main()
{
	test01();
	test02();
	system("pause");
	return 0;
}
2.10 THIS指针的用途

每一个非静态成员函数只会诞生一份函数实例,也就是多个同类型的对象会公用一块代码,this指针指向被调用的成员函数所属的对象
THIS指针是隐含每一个非静态成员函数内的一种指针,不需要定义,直接使用
用途:当形参和成员变量同名时,可以用THIS指针来区分;在类的非静态成员函数中返回对象本身,可以使用 RETURN *THIS

#include<iostream>
#include<string>
using namespace std;
//解决名称冲突
class Person
{
public:
	int age;
	Person(int age)
	{
		//age = age;//编译器认为三个age是同一个,没有和成员变量区分开
		this->age = age;//this指针指向被调用的成员函数所属的对象
	}
	void Personaddage(Person& p)
	{
		this->age += p.age;//两个变量的AGE相加 || 一个变量的AGE累加
	}
	//用引用来接收
	Person& Personaddage1(Person& p)
	{
		this->age += p.age;//两个变量的AGE相加 || 一个变量的AGE累加
		return *this;//返回对象本身
	}
	Person Personaddage2(Person& p)
	{//返回值
		this->age += p.age;
		return *this;
	}
};

void test01()
{
	Person p1(18);
	cout << "p1的年龄是  " << p1.age << endl;
}
void test02()
{
	Person p(80);
	p.Personaddage(p);
	cout << "p的年龄是  " << p.age << endl;
	Person p1(2);
	p.Personaddage(p1);
	cout << "p的年龄是  " << p.age << endl;
	//p.Personaddage(p1).Personaddage(p1).Personaddage(p1).Personaddage(p1);
	//超级连加,错误,第一次函数运算完成,返回一个VOID
	p.Personaddage1(p1).Personaddage1(p1).Personaddage1(p1).Personaddage1(p1);//链式编程思想
	cout << "p的年龄是  " << p.age << endl;
	p.Personaddage2(p1).Personaddage2(p1).Personaddage2(p1).Personaddage2(p1);//链式编程思想
	//只运算了第一次,值返回就是?复制一份?和本体值相同,但是不是本体了
	cout << "p的年龄是  " << p.age << endl;
}
int main()
{
	test01();
	test02();
	system("pause");
	return 0;
}
2.11 空指针访问成员函数

C++中空指针也是可以调用成员函数,但是也要注意有么有用到THIS指针
如果用到,需要加以判断保证代码的健壮性?

#include<iostream>
#include<string>
using namespace std;
//解决名称冲突
class Person
{
public:
	int m_age;
	void showPersonName()
	{
		cout << "this is Person Class" << endl;
	}
	void showPersonAge()
	{
		if (this == NULL)
		{
			return;//不会走到下一步
		}
		cout << "m_age=" << m_age << endl;
		//cout << "m_age=" << this->m_age << endl;但是this现在是一个空指针,
	}
};

void test01()
{
	Person* p = NULL;
	p->showPersonName();
	//p->showPersonAge();//报错
}

int main()
{
	test01();
	system("pause");
	return 0;
}
2.12 COSNT修饰成员函数

成员函数后加CONST后-》常函数;常函数不可以修改成员属性,成员属性声明时加关键字MUTABLE后,常函数中依然可修改
在成员函数后加CONST,本质上修饰的时THIS指针,让指针指向的值也不可修改
常对象:声明对象前加CONST,常对象只能调用常函数

#include<iostream>
#include<string>
using namespace std;
//解决名称冲突
class Person
{
public:
	int m_age;//不能直接设置一个初始值,反而会报错受用未初始化的内存p
	mutable int m_b;//特殊变量,常函数中也可以修改
	void showage()const//(const) Person *const this
	//在成员函数后加CONST,本质上修饰的时THIS指针,让指针指向的值也不可修改
	{
		//m_age = 100;不可修改
		//this->m_age = 100;
		//this 指针的本质,指针常量,指针的指向不可修改,Person *const this
		//this = NULL;不可修改
		cout << "m_age=" << m_age << endl;
		m_b = 232;
		cout << "m_b=" << m_b << endl;//特殊变量可以修改
	}
	void func(){}
};
void test01()
{
	Person p;
	p.showage();
}
void test02()
{
	const Person p;//常对象
	//p.m_age = 1000;//不可修改
	p.m_b = 454;//可以修改
	p.showage();//常对象只能调用常函数
	//p.func();//不可以调用普通成员函数,因为普通成员函数可以修改属性
}
int main()
{
	test01();
	system("pause");
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

揭秘分销系统:商业模式的新风向

大家好&#xff0c;我是微三云周丽&#xff0c;今天给大家分析当下市场比较火爆的商业模式&#xff01; 小编今天跟大伙们分享什么是分销系统&#xff1f; 在数字化浪潮席卷全球的今天&#xff0c;电子商务以其独特的优势&#xff0c;正在重塑商业世界的格局。其中&#xff0…

css设置输入框边框无效或者不展示边框

bug描述&#xff1a;在聚焦的时候&#xff0c;期望输入框的边框是主题色&#xff0c;但是不知道是个啥颜色。 发现输入框input以及textarea样式css标签:focus更改样式无效这个问题。 若希望实现input在触发焦点时更改样式&#xff0c;通常会想到使用:focus选择器&#xff0c;…

积极探索新质生产力,九河云携手华为云技术交流引领数智跃迁

4月18日&#xff0c;九河云携手华为云举办了华为云SA技术培训会议&#xff0c;培训邀请到华为云技术人员作为主讲人&#xff0c;通过理论讲解与案例结合的方式&#xff0c;围绕ECS和EBS之间的联动&#xff0c;调优和数据保护等方面展开&#xff0c;深入浅出地讲解了基于EBS部署…

uniapp 引用组件后 不起作用 无效果 不显示

根据uniapp官方文档easycom组件规范 只要组件安装在项目的components目录下或uni_modules目录下&#xff0c;并符合components/组件名称/组件名称.(vue|uvue)目录结构&#xff08;注意&#xff1a;当同时存在vue和uvue时&#xff0c;uni-app 项目优先使用 vue 文件&#xff0c;…

浅谈防火墙,IPS,APT威胁检测的互补性

在学习网络安全产品时发现很多产品的目的与功能大同小异都是防范非法流量或威胁&#xff0c;但是既然有产品的差异就有作用的目的的差异&#xff0c;下面浅谈一下三个网络安全产品的差异化与互补点 防火墙 传统防火墙主要是工作在二到四层&#xff0c;不会对报文的载荷进行检…

App Cleaner Uninstaller中文激活版:mac最强深度清理软件

App Cleaner & Uninstaller 是一款适用于 Mac 操作系统的软件应用程序&#xff0c;允许用户轻松卸载不需要的应用程序、删除剩余文件和文件夹以及管理启动项。该应用程序会分析与您要删除的应用程序关联的文件&#xff0c;并帮助识别其所有组件&#xff0c;以便您可以一次将…

中红医疗:纷享销客CRM系统如何助力​数字化“狂飙”

纷享销客深耕 CRM 多年&#xff0c;可以顺畅打通 CRM 和 ERP 系统客户资源池&#xff0c;将金蝶苍穹平台的物料、产品基础主数据作为档案同步到纷享销客&#xff0c;以便商务维护好产品及库存。 纷享销客通过成熟的集成方案提高系统耦合性&#xff0c;让销售实时获得新产品及营…

JsonPath实战

概述 JsonPath&#xff0c;GitHub是一种简单的方法来提取给定JSON文档的部分内容&#xff0c;提供类似正则表达式的语法来解析JSON文档。 特性 入门 引入如下Maven依赖&#xff1a; <dependency><groupId>com.jayway.jsonpath</groupId><artifactId&…

用Python将原始边列表转换为邻接矩阵

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在图论和网络分析中&#xff0c;图是一种非常重要的数据结构&#xff0c;它由节点&#xff…

驱动比例换向阀放大器

比例换向阀放大器技术是电液比例系统中关键的组成部分&#xff0c;它主要用于控制比例阀&#xff0c;实现对液压流量或压力的精确控制。 高精度控制&#xff1a;通过比例阀放大器&#xff0c;系统可以非常精确地调节液压流量或压力&#xff0c;这对于要求精密操作的机械系统来说…

DSP系统的设计过程与选型

DSP的设计步骤分几个阶段&#xff0c;应用系统的设计过程如图所示。 技术指标的确定 器件的选型原则 其他因素的考虑

学习c语音的自我感受

因为是自学&#xff0c;所以走过不少弯路。去年&#xff0c;受知乎“python性能弱”风潮的影响&#xff0c;学过go,rust。 在学习这些新语言的时候&#xff0c;由衷感受到&#xff0c;或是本身侧重方向的原因&#xff08;如go侧重服务器&#xff09;&#xff0c;或是语言太新不…

Php-WebView 现代跨平台 GUI分享

GitHub :php-webview 一个用于 C/C 的小型跨平台 Web 视图库&#xff0c;用于构建现代跨平台 GUI。 该项目的目标是为最广泛使用的平台创建一个通用的 HTML5 UI 抽象层。 它支持双向 JavaScript 绑定&#xff08;从 C/C 调用 JavaScript 和从 JavaScript 调用 C/C&#xff09;。…

蛋白质致病突变的计算方法(四)

3.1.5 域定位 (domain location) 残基在序列中的位置可分为N-terminal(1-30%)、中间(31-70%)和C-terminal(71-100%)。Singh等人报告称&#xff0c;TP53的中心和高度保守的DNA结合域包含一簇体细胞错义突变&#xff0c;包括R175、G245、R248和R273。这些突变形成与DNA的直接接触…

Docker 部署 WordPress 并完成建站

什么是 WordPress WordPress 是使用 PHP 语言开发的博客平台&#xff0c;用户可以在支持 PHP 和 MySQL 数据库的服务器上架设属于自己的网站。也可以把 WordPress 当作一个内容管理系统&#xff08;CMS&#xff09;来使用。WordPress 是一款个人博客系统&#xff0c;并逐步演化…

DC-DC电源设计中电感选型详解

电感参数: DC-DC 电感选型步骤: 1, 根据 DC-DC 的输入输出特性计算所需的最小电感量。 (1)对于 Buck 型 DC-DC,计算公式如下 Lmin= 【Vout*(1-Vout/Vinmax)】/ (Fsw*Irpp ) 其中: Vinmax = maximum input voltage Vout = output voltage fsw = switching frequency…

第二届阿里巴巴大数据智能云上编程大赛亚军比赛攻略_北方的郎队

关联比赛: 第二届阿里巴巴大数据智能云上编程大赛-智联招聘人岗智能匹配 查看更多内容&#xff0c;欢迎访问天池技术圈官方地址&#xff1a;第二届阿里巴巴大数据智能云上编程大赛亚军比赛攻略_北方的郎队_天池技术圈-阿里云天池

Pytorch:张量的梯度计算

目录 一、自动微分简单介绍1、基本原理2、梯度计算过程3、示例&#xff1a;基于 PyTorch 的自动微分a.示例详解b.梯度计算过程c.可视化计算图 4、总结 二、为什么要计算损失&#xff0c;为何权重更新是对的&#xff1f;1、梯度下降数学原理2、梯度上升 三、在模型中使用自动微分…

Qt 菜单栏上手教程:QMenuBar QMenu QToolbar

引言 在Qt框架中&#xff0c;QMenuBar、QMenu、QToolbar和QAction都是用于构建应用程序界面中的用户交互元素。 QMenuBar 是什么&#xff1a;QMenuBar是一个用于创建横向菜单栏的类。在桌面应用程序中&#xff0c;它通常位于窗口的顶部。应用场景&#xff1a;当您需要一个包含…

CTF小工具

1 ciphey https://github.com/Ciphey/Ciphey Ciphey 是一个使用自然语言处理和人工智能的全自动解密/解码/破解工具。 简单地来讲&#xff0c;你只需要输入加密文本&#xff0c;它就能给你返回解密文本。就是这么牛逼。 有了Ciphey&#xff0c;你根本不需要知道你的密文是哪…
最新文章