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();//输出100cout << 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);//超级连加,错误,第一次函数运算完成,返回一个VOIDp.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;//不能直接设置一个初始值,反而会报错受用未初始化的内存pmutable 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.rhkb.cn/news/311497.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android不同版本(支持>10)获取当前连接的wifi名称

1、AndroidManifest.xml 配置权限 <uses-permission android:name"android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name"android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name&q…

设定延迟任务和定时任务并优化定时任务

一丶设定延时任务 1.设定延迟任务要求如下 ①在系统中建立easylee用户&#xff0c;设定其密码为easylee ②延迟任务由root用户建立 ③要求在5小时后备份系统中的用户信息文件到/backup中 ④确保延迟任务是使用非交互模式建立 ⑤确保系统中只有root用户和easylee用户可以执…

【Java开发指南 | 第八篇】Java变量、构造方法、创建对象

读者可订阅专栏&#xff1a;Java开发指南 |【CSDN秋说】 文章目录 Java变量构造方法创建对象 Java变量 在Java中&#xff0c;变量用于存储数据值。它们是程序中用于保存信息的一种基本方式。变量在程序执行过程中可以被赋予不同的值&#xff0c;并且这些值可以在程序的不同部分…

自定义类型: 结构体 (详解)

本文索引 一. 结构体类型的声明1. 结构体的声明和初始化2. 结构体的特殊声明3. 结构体的自引用 二. 结构体内存对齐1. 对齐规则2. 为啥存在对齐?3. 修改默认对齐值 三. 结构体传参四. 结构体实现位段1. 什么是位段?2. 位段的内存分配3. 位段的应用4. 位段的注意事项 ​ 前言:…

【C语言】带你完全理解指针(六)指针笔试题

目录 1. 2. 3. 4. 5. 6. 7. 8. 1. int main() {int a[5] { 1, 2, 3, 4, 5 };int* ptr (int*)(&a 1);printf("%d,%d", *(a 1), *(ptr - 1));return 0; } 【答案】 2&#xff0c;5 【解析】 定义了一个指向整数的指针ptr&#xff0c;并将其初始化为&…

通过Omnet++官网tictoc教程学习在Omnet++中构建和运行仿真 Part4

官方链接 文章目录 Part4&#xff1a;让仿真更像实际网络增加节点信道和内部类型定义双向连接的链路自定义消息类 Part4&#xff1a;让仿真更像实际网络 增加节点 现在我们将迈出一大步:创建几个tic模块并将它们连接到一个网络中。现在&#xff0c;我们将保持简单:其中一个节…

苹果电脑启动磁盘是什么意思 苹果电脑磁盘清理软件 mac找不到启动磁盘 启动磁盘没有足够的空间来进行分区

当你一早打开苹果电脑&#xff0c;结果系统突然提示&#xff1a; “启动磁盘已满&#xff0c;需要删除部分文件”。你会怎么办&#xff1f;如果你认为单纯靠清理废纸篓或者删除大型文件就能释放你的启动磁盘上的空间&#xff0c;那就大错特错了。其实苹果启动磁盘的清理技巧有很…

pyside6自定义部件库和软件框架的建设记录

自定义的部件库原则上尽量做到前后端分离&#xff0c;接口方便&#xff0c;复制简单。 单选框部件 # encoding: utf-8 ################################################### # 自定义的单选框 #################################################### 对外接口&…

蓝桥杯2024年第十五届省赛真题-R 格式(高精度乘法 + 加法)

本题链接&#xff1a;蓝桥杯2024年第十五届省赛真题-R 格式 - C语言网 题目&#xff1a;​​​​​​​ 样例&#xff1a; 输入 2 3.14 输出 13 思路&#xff1a; 根据题意&#xff0c;结合数据范围&#xff0c;这是一道模板的高精度乘以低精度问题。 题意是double 类型 d 与…

【C++】类和对象③(类的默认成员函数:拷贝构造函数 | 赋值运算符重载)

&#x1f525;个人主页&#xff1a;Forcible Bug Maker &#x1f525;专栏&#xff1a;C 目录 前言 拷贝构造函数 概念 拷贝构造函数的特性及用法 赋值运算符重载 运算符重载 赋值运算符重载 结语 前言 本篇主要内容&#xff1a;类的6个默认成员函数中的拷贝构造函数…

由于找不到krpt.dll,无法继续执行代码的5种解决方法

在正常使用电脑的过程中&#xff0c;当尝试启动某个应用程序或者执行特定功能时&#xff0c;系统突然弹出一个错误提示窗口&#xff0c;明确指出由于缺失关键性文件——krpt.dll&#xff0c;导致当前运行的软件无法正常读取并执行相应的程序代码&#xff0c;进而无法顺利完成预…

Neo4j 图形数据库中有哪些构建块?

Neo4j 图形数据库具有以下构建块 - 节点属性关系标签数据浏览器 节点 节点是 Graph 的基本单位。 它包含具有键值对的属性&#xff0c;如下图所示。 NEmployee 节点 在这里&#xff0c;节点 Name "Employee" &#xff0c;它包含一组属性作为键值对。 属性 属性是…

Hit the World Hit世界 Hit2日服官网地址+配置要求+测试时间

Hit the World/Hit世界/Hit2日服官网地址配置要求测试时间 Hit the World/Hit世界是NEXON旗下MMOROG游戏&#xff0c;作品类型上是典型的类天堂游戏&#xff0c;升级思路很简单&#xff0c;一般是跟着主线走&#xff0c;除了主线还有副本升级。支持移动和PC两端&#xff0c;继…

1113. 红与黑--Flood Fill 算法

目录 1113. 红与黑--Flood Fill 算法---宽搜&#xff08;BFS&#xff09;或DFS&#xff09; 输入格式 输出格式 数据范围 输入样例&#xff1a; 输出样例&#xff1a; 思路&#xff1a; 1.BFS 思路&#xff1a; 2.DFS 思路 方法一&#xff1a;&#xff08;BFS&#x…

STM32H7的8个串口fifo收发(兼容232和485)

STM32H7的8个串口fifo收发&#xff08;兼容232和485&#xff09; 串口硬件串口时序串口高级特性同步和异步的区别单工、半双工、全双工的区别 STM32H78个串口fifo驱动定义数据结构uart_fifo.huart驱动包括中断配置等 应用示例RS485深入理解 仅供学习。 USART 的全称是 Universa…

【电控笔记6.2】拉式转换与转移函数

概要 laplace&#xff1a;单输入单输出&#xff0c;线性系统 laplace 传递函数 总结

sqlilabs靶场1—20题学习笔记(思路+解析+方法)

前几个题目较为简单&#xff0c;均尝试使用各种方法进行SQL注入 第一题 联合查询 1&#xff09;思路&#xff1a; 有回显值 1.判断有无注入点 2.猜解列名数量 3.判断回显点 4.利用注入点进行信息收集 爆用户权限&#xff0c;爆库&#xff0c;爆版本号 爆表&#xff0c;爆列&…

全球顶级的低代码开发平台,你知道几个?

什么是低代码开发平台? 低码开发平台是一个应用程序,提供图形用户界面编程,从而以非常快的速度开发代码,减少了传统的编程工作。 这些工具有助于快速开发代码,最大限度地减少手工编码的努力。这些平台不仅有助于编码,而且还能快速安装和部署。 低码开发工具的好处 低代码平…

3dmax在线渲染怎么取消?怎么关闭云渲染

在线渲染&#xff0c;无论是通过云渲染服务还是渲染农场&#xff0c;已经成为众多3dmax动画制作者的首选方式来执行渲染任务。然而&#xff0c;如果在渲染过程中需要禁用这一在线渲染功能&#xff0c;该怎么操作呢&#xff1f;接下来&#xff0c;让我们一起探讨如何关闭这一功能…

【精读文献】Scientific data|2017-2021年中国10米玉米农田变化制图

论文名称&#xff1a;Mapping annual 10-m maize cropland changes in China during 2017–2021 第一作者及通讯作者&#xff1a;Xingang Li, Ying Qu 第一作者单位及通讯作者单位&#xff1a;北京师范大学地理学部 文章发表期刊&#xff1a;《Scientific data》&#xff08…