[C++]类与对象(上)

news2025/1/14 11:55:22

目录

 💕1.C++中结构体的优化

 💕2.类的定义

💕3.类与结构体的不同点

💕4.访问限定符(public,private,protected)

 💕5.类域

💕6.类的实例化 

💕7.类的字节大小

💕8.类的字节大小特例

 💕9.this指针


  

 (最新更新时间——2025.1.13)

因为困难多壮志,不教红尘惑坚心

        今身暂且栖草头,他日狂歌踏山河

 💕1.C++中结构体的优化

在C++中,结构体的使用得到了优化,具体优化了什么呢?请看以下代码->:

struct student
{
	int age;
	double num;
};

int main()
{
	struct student s1;//C语言中书写,C++也兼容
	student s1;//C++中优化
	return 0;
}

我们在C语言中书写时,需要把struct把写上,而在C++中得到了优化,不需要写struct,直接写结构体的名称也可以使用


同时我们也可以在struct中定义函数

struct student
{
	int age;
	double num;
	int add(int a, int b)
	{
		return a + b;
	}
};

int main()
{
	student s1;//C++中优化
	cout<<s1.add(10, 20);//输出30
	return 0;
}


 💕2.类的定义

我们回到正题,什么是类?

类其实就是结构体的优化,我们将struct 更改为 class,就属于变为了类


先看一段代码,在这串代码中,class 是类的关键字,student 是类的名字

{ }为类的主体,类中的变量称为类的属性或成员变量,

class student
{    
    //类的⽅法或者成员函数
	int add(int a, int b)
	{
		return a + b;
	}

    //类的属性或者成员变量
	int age;
	double num;
};

int main()
{
	student s1;//创建类变量s1
}

就此看来,类与结构体还没有不同点,那么不同点在哪呢?

💕3.类与结构体的不同点

类中的成员函数是与成员变量密切相关的,即同一类中,成员函数可以给成员变量赋值,并且成员变量也可以作为成员函数的参数,我们举个例子->:

如图所示,即使我们不进行传参,成员函数内也可以找到类中对应的成员变量,而结构体却不可以

因此->:在类中创建的成员变量,在类中是直接可以用的

💕4.访问限定符(public,private,protected)

在C++中,类的定义中新建了三种权限关系,分别是public,private,与protected

这些的意义是什么呢?


C++⼀种实现封装的⽅式,⽤类将对象的属性与⽅法结合在⼀块,让对象更加完善,通过访问权限

选择性的将其接⼝提供给外部的⽤⼾使⽤

public修饰的成员在类外可以直接被访问;protected和private修饰的成员在类外不能直接被访 问,protected和private是⼀样的,以后继承章节才能体现出他们的区别,接下来是代码举例->:

我们可以发现,我们在类中的成员函数设置为private,只可以在类的内部使用,那么在类的外部就不能使用这些成员函数,这就是private的作用


那如果把它换成public呢?

效果如下->:更换成public后,权限被更改为公有的,在类外面也可以进行使用


如果我们访问限定符什么都不写的话,系统会默认全部设为private


 💕5.类域

讲类域之前,我们先讲一个简单的例子

class student
{
	int age;
	int year;
};
int main()
{
	
}

这是的类叫做类的声明还是定义?


答案是声明,类的定义是会开创出空间的,而此时的类没有任何的变量并不会开创空间,所以此时叫做类的定义,那既然是类的定义,那可不可以写在 .h 文件中,答案是可以的,接下来请看代码->:


.h文件>:

#pragma once
#include<iostream>
#include"abc.h"
using namespace std;

class Date{
public:
	void Init(int year, int month, int day);
	int _year;
	int _month;
	int _day;
};

我们可以在.h中实现类的声明,那类中成员函数的实现怎么办,我们以往的经验是写在函数功能实现的.c文件中,在C++中也是一样的,只不过有一点不同


函数实现文件.c->:

#define _CRT_SECURE_NO_WARNINGS 
#include"achie.h"

void Date:: Init(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;
}

在这些代码中,我们看到了类中成员函数的实现,有许多人都会注意到了 Date:: ,这是什么意思?这是因为类域的存在,我们知道函数的实现依靠的是函数的地址,而编译器寻找的方式是全局域,局部域,命名作用域与类域,我们的Init写在了类域中,编译器在全局域与局部域都找不到,而命名作用域与类域都是需要特殊指定的域,所以如果不声明编译器就找不到这个函数在哪,我们可以试一下不指定后的样子:


以下分别是.h与函数实现的.c文件中的图片,可以看到.h中说明找不到函数的定义,因为在函数实现.c文件中,并没有找到Init函数的地址

💕6.类的实例化 

类是对象进⾏⼀种抽象描述,是⼀个模型⼀样的东西,限定了类有哪些成员变量,这些成员变量只 是声明,没有分配空间,⽤类实例化出对象时,才会分配空间
⼀个类可以实例化出多个对象,实例化出的对象 占⽤实际的物理空间,存储类成员变量。打个⽐ ⽅:类实例化出对象就像现实中使⽤建筑设计图建造出房⼦,类就像是设计图,设计图规划了有多 少个房间,房间⼤⼩功能等,但是并没有实体的建筑存在,也不能住⼈,⽤设计图修建出房⼦,房 ⼦才能住⼈。同样类就像设计图⼀样,不能存储数据,实例化出的对象分配物理内存存储数据。

一个类可以实例出多个对象的代码演示->:

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
using namespace std;

class Date {
public:
	void Init(int year, int month, int day)
	{
			_year = year;
			_month = month;
			_day = day;
	}
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date a1;
	Date a2;
	Date a3;
}

这里就是类与对象的关系,一个类可以有多个对象,如果有拿这段代码去运行而报错的同志,那就是因为对象创建出来后没有手动初始化,注意是手动(后面讲)

💕7.类的字节大小

类的字节大小是怎么计算的,其实与我们在C语言中学的结构体极其类似,具体在哪不同,我们接着看->:

我们可以看到是12个字节,为什么?

其实这里与我们在C语言中学习的结构体内存存储方式基本相同,如果不懂的具体请看这篇文章,我们这里只讲不同点->:

C语言结构体详解(超全)简单易懂(代码+万字文字+画图讲解)


不同点在于->:当我们计算类的字节大小时,我们会思考,类中的函数存储在哪?

⾸先函数被编译后是⼀段指令,对象中没办法存储,因此这些指令存储在⼀个单独的区域(代码段)

也就是说明类中的成员函数存储在公共代码区,这也意味着每个对象所使用的函数是共同的,并不会因为每有一个类就创建一个它自己的函数,它与其他对象所使用的函数是共同的


我们知道,函数的使用是相当频繁地,如果一个对象使用100次函数,那么创建出来的空间是非常大的,因此函数的地址会存放在公共代码区,避免空间重复,浪费空间


注意->:对象中的每个成员变量是独立的成员变量

💕8.类的字节大小特例

为什么输出的字节是1呢?

类中的成员变量为空,不应该输出0吗?

其实这个1字节是为了识别出类而开辟的,所以是1


那这样呢?

这样输出的1跟之前所输出1的原因是相同的,都是为了识别出类的存在

 💕9.this指针

在类的函数中,其实有一个隐藏的 this 指针,什么是隐藏的 this 指针?

其实当我们调用类中的成员函数时,会将这个对象的地址传输过去,什么意思?请看代码->:

在我们调用函数时,就会将对象的地址传输过去,并在成员函数的形参处用Date* const this来接受,为什么会报错?这是因为->:


C++规定不能在实参和形参的位置显⽰的写this指针(编译时编译器会处理),但是可以在函数体内使⽤this指针,什么意思?请看下图->:


这里的this可以写也可以不写,主要是为了演示一遍,这里的this指的就是对象a1的地址


小题思考->:

我们思考一下,下面这串代码的运行结果是什么->:

#include<iostream>
using namespace std;
//A.编译报错 B.运行崩溃 C.正常运行
class A
{
public:
	void Print()
	{
		cout << "A::Print()" << endl;
	}
private:
	int _a;
};
int main()
{
	A* p = nullptr;
	p->Print();
	return 0;
}

其实是正常运行,在这里传递的是p,也就是一级指针,传空指针是没有问题的,空指针只有在解引用时候才会报错,而这里并没有进行解引用,也就是说会正常运行


再来看一道
 

#include<iostream>
using namespace std;
//A.编译报错 B.运行崩溃 C.正常运行
class A
{
public:
	void Print()
	{
		cout << "A::Print()" << endl;
		cout << _a << endl;
	}
private:
	int _a;
};
int main()
{
	A* p = nullptr;
	p->Print();
	return 0;
}

这道题就不会正常运行了,而是运行崩溃,因为从语法上看,this->a 等价于 (*this).a。这里的 *this 就是对 this 指针的解引用,它获取了 this 所指向的对象本身,然后通过 . 操作符访问该对象的成员变量 a

空指针被解引用了,所以运行崩溃了


最后一道思考->:

3. this指针存在内存哪个区域的 ()
A. 栈 B.堆 C.静态区 D.常量区 E.对象⾥⾯

这里的答案是栈区,因为this指针是形参,而形参是存储在栈区的

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

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

相关文章

Sprint Boot教程之五十八:动态启动/停止 Kafka 监听器

Spring Boot – 动态启动/停止 Kafka 监听器 当 Spring Boot 应用程序启动时&#xff0c;Kafka Listener 的默认行为是开始监听某个主题。但是&#xff0c;有些情况下我们不想在应用程序启动后立即启动它。 要动态启动或停止 Kafka Listener&#xff0c;我们需要三种主要方法…

《JavaWeb开发-javascript基础》

文章目录 《JavaWeb开发-javascript基础》1.javascript 引入方式2.JS-基础语法-书写语法2.1 书写语法2.2 输出语句 3.JS-基础语法-变量4.JS-基础语法-数据类型&运算符4.1 数据类型4.2 运算符4.3 数据类型转换 5. JS-函数6. JS-对象-Array数组7. JS-对象-String字符串8. JS-…

1.组件的三大组成部分注意点(结构/样式/逻辑)scoped解决样式冲突/data是一个函数2.组件通信组件通信语法父传子子传父

学习目标 1.组件的三大组成部分注意点&#xff08;结构/样式/逻辑&#xff09; scoped解决样式冲突/data是一个函数 2.组件通信 组件通信语法 父传子 子传父 非父子通信&#xff08;扩展&#xff09; 3.综合案例&#xff1a;小黑记事本&#xff08;组件版&#xff09; …

mapbox基础,expressions表达式汇总

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言二、🍀Expressions简介2.1 expressions 操作符2.1.1 Data expressions2.1.2 Camera expressions2.2 Expressi…

一文清晰梳理Mysql 数据库

现在处于大四上学期的阶段&#xff0c;在大四下学期即将要进行毕业设计&#xff0c;所以在毕业设计开始之前呢&#xff0c;先将Mysql 数据库有关知识进行了一个梳理&#xff0c;以防选题需要使用到数据库。 1&#xff09;什么是数据库&#xff1f; 简单理解数据库&#xff0c…

基于大语言模型的组合优化

摘要&#xff1a;组合优化&#xff08;Combinatorial Optimization, CO&#xff09;对于提高工程应用的效率和性能至关重要。随着问题规模的增大和依赖关系的复杂化&#xff0c;找到最优解变得极具挑战性。在处理现实世界的工程问题时&#xff0c;基于纯数学推理的算法存在局限…

安装conda 环境

conda create -n my_unet5 python3.8 conda activate my_unet5

容器技术全面攻略:Docker的硬核玩法

文章背景 想象一下&#xff0c;一个项目终于要上线了&#xff0c;结果因为环境配置不一致&#xff0c;测试服务器一切正常&#xff0c;生产环境却宕机了。这是开发者噩梦的开始&#xff0c;也是Docker救世主角色的登场&#xff01;Docker的出现颠覆了传统环境配置的方式&#…

LabVIEW部署Web服务

目录 LabVIEW部署Web服务1、创建项目2、创建Web服务3、新建WebVI3.1、使用GET方法3.2、使用POST方法 4、 部署和对应URL4.1、应用程序&#xff1a;80804.2、本地调试&#xff1a;80094.3、NI Web服务器&#xff1a;9090(禁用) 5、测试5.1、测试GET方法5.2、测试POST方法 6、实际…

STM32 : 波特率发生器

波特率发生器 1. 发送器和接收器的波特率 波特率寄存器 (BRR): 在串行通信中&#xff0c;发送器和接收器的波特率是由波特率寄存器&#xff08;BRR&#xff09;中的一个值 DIV 来确定的。 2. 计算公式 计算公式: 详细解释 1. 波特率寄存器 (BRR) BRR: 波特率寄存器是一…

Excel数据叠加生成新DataFrame:操作指南与案例

目录 一、准备工作 二、读取Excel文件 三、数据叠加 四、处理重复数据&#xff08;可选&#xff09; 五、保存新DataFrame到Excel文件 六、案例演示 七、注意事项 八、总结 在日常数据处理工作中&#xff0c;我们经常需要将不同Excel文档中的数据整合到一个新的DataFra…

基于微信小程序的汽车销售系统的设计与实现springboot+论文源码调试讲解

第4章 系统设计 一个成功设计的系统在内容上必定是丰富的&#xff0c;在系统外观或系统功能上必定是对用户友好的。所以为了提升系统的价值&#xff0c;吸引更多的访问者访问系统&#xff0c;以及让来访用户可以花费更多时间停留在系统上&#xff0c;则表明该系统设计得比较专…

C#调用OpenCvSharp实现图像的开运算和闭运算

对图像同时进行腐蚀和膨胀操作&#xff0c;顺序不同则效果也不同。先腐蚀后膨胀为开运算&#xff0c;能够消除小斑点和细小的突出物、平滑图像以及改善边缘&#xff1b;先膨胀后腐蚀为闭运算&#xff0c;能够去除噪点、填补图像孔洞、连接邻近物体和平滑物体边界。   OpenCvS…

从 SQL 语句到数据库操作

1. SQL 语句分类 数据定义语言 DDL &#xff1a; 用于定义或修改数据库中的结构&#xff0c;如&#xff1a;创建、修改、删除数据库对象。create、drop alter 数据操作语言 DML &#xff1a; 用于添加、删除、更新数据库中的数据。select、insert alter、drop 数据控制语言 D…

django在线考试系统

Django在线考试系统是一种基于Django框架开发的在线考试平台&#xff0c;它提供了完整的在线考试解决方案。 一、系统概述 Django在线考试系统旨在为用户提供便捷、高效的在线考试环境&#xff0c;满足教育机构、企业、个人等不同场景下的考试需求。通过该系统&#xff0c;用…

【Spring Boot 应用开发】-04-01 自动配置-数据源-连接池

资源关闭 还记得上一节中的这段代码么&#xff1f; try {if (resultSet ! null) resultSet.close();if (preparedStatement ! null) preparedStatement.close();if (connection ! null) connection.close(); } catch (SQLException e) {e.printStackTrace(); }这是我们在查询…

AngularJs指令中出错:Error: $compile:nonassign Non-Assignable Expression

Expression {resumeId: item.resumeId} used with directive rwdsDelete is non-assignable! 在AngularJS中&#xff0c;$compile服务用于将指令编译成HTML。当你在模板中使用了一个表达式&#xff0c;但这个表达式不是一个左值&#xff08;即不能被赋值的表达式&#xff09;时…

Docker 的安装和基本使用[SpringBoot之Docker实战系列] - 第535篇

历史文章&#xff08;文章累计530&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 《…

聚铭网络当选中关村华安关键信息基础设施安全保护联盟理事单位

近日&#xff0c;在北京隆重举行的中关村华安关键信息基础设施安全保护联盟&#xff08;以下简称“联盟”&#xff09;第一届第四次会员大会上&#xff0c;聚铭网络凭借其在网络安全领域的卓越贡献和创新实力&#xff0c;成功当选为联盟的理事单位。此次大会吸引了来自政府机关…

CES 2025|全面拥抱端侧AI,美格智能在CES发布系列创新成果

要点&#xff1a; ▶ 在AI机器人领域&#xff0c;以高算力AI模组助力发布“通天晓”人形机器人和2款全新微小型AI机器人 ▶ 在AI硬件领域&#xff0c;发布消费级AI智能体产品——AIMO&#xff0c;引领个人专属的大模型时代 ▶ 在5G通信领域&#xff0c;发布全新5GWiFi-7 CPE…