C++初阶之类与对象(上)详细解析

个人主页:点我进入主页

专栏分类:C语言初阶  C语言进阶  数据结构初阶    Linux    C++初阶    

欢迎大家点赞,评论,收藏。

一起努力,一起奔赴大厂

 

目录

 

一.前言

二.类的定义和使用

2.1类的引入

2.2类的定义和访问限定符

2.21定义

2.2.2访问限定符

2.2.3代码示例以及对上面的分析

2.2.4封装

2.3类的内存对齐

2.3.1类中的函数的位置

2.3.2小问题

2.3.3内存对齐

2.3.4内存对齐意义


 

一.前言

        在前面我们写过C++入门中的函数重载,命名空间,缺省参数,引用,还有一些新的语法, 这些内容是我们学习后面的基础,在今天我主要给大家带来关于类的内容,其中包括类的定义和使用,访问限定符封装,类的实例化,计算类的大小以及内存对齐。

二.类的定义和使用

2.1类的引入

        在c语言期间我们的结构体你还记得吗?在C++中祖师爷对它进行了升级,升级成了我们的类,我们写一个代码表示C语言中的结构体:

struct A {int num1;int num2;int* p;
};

我们定义变量时使用:

struct A a;

如果我们想定义一个函数,我们需要在结构体外进行声明和定义。

那我们在C++中是如何使用结构体呢?我们看下面的代码

struct Data {int _year;int _month;int _day;void Init(int year, int month, int day){_year = year;_month = month;_day = day;}
};int main()
{Data d1;d1.Init(2024, 1, 31);return 0;
}

在C++中我们更喜欢使用class来定义。

2.2类的定义和访问限定符

2.21定义

        class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。(也就是说我们将class代替我们的struct,当然struct也可以,{}中包含的分为两部分一是成员变量,一部分是成员函数)。

2.2.2访问限定符

        访问限定符包括3个分别是public(公开),private(私有),protected(保护),其中public可以任意访问,protected和private不能任意访问只能在类里面访问,访问权限是从第一个访问限定符到下一个访问限定符之间,struct默认为public,class默认为private。

2.2.3代码示例以及对上面的分析

#include<iostream>
using namespace std;class Data {
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << "/" << _month << "/" << _day << endl;}
private:int _year;int _month;int _day;
};int main()
{Data d1;d1.Init(2024, 2, 1);d1.Print();return 0;
}

        我们采用class的形式,我们的第一个限定词是public第二个限定词是private,其中public的作用域是public到private,private的作用域是从private到结尾。在main函数中我们定义的d1可以称为我们的对象,我们访问public作用域的内容时我们直接利用对象去访问,下面的访问方式是不对的:

	Init(2024, 2, 1);Data::Init(2024, 2, 1);

ea91906658b94a8c97dc5d88d7a7c4d9.png

这两种都存在存在问题,都是不正确的,对于public作用域的我们可以在类的里面和外面进行访问   ,那对于private或protect作用域的内容呢?我们看到在定义Init函数时我们在类里面就使用了我们private的内容,因此在类里面可以访问,那类外面呢?我们看下面

	d1._year = 1;Data::_year;

这两种都是会报错的

252078794bd242e3b448ebc423ee2abb.png

所以我们可以看到private作用域的变量或函数只能在类里面进行访问,不能在类外访问,由于private和protect在这里一样,所以不做过多演示。

2.2.4封装

        我们可以将封装看成一种管控,c++将变量和方法放在类里面,允许让我们访问的使用public进行修饰,不想让我们访问的使用private或protected进行修饰。

2.3类的内存对齐

2.3.1类中的函数的位置

        我们需要知道,类中函数的位置,类中函数和成员变量是放在不同的位置,

5cd1913f4be04223a6b5bc1273f69a3c.png

如果我们定义一个指针

	Data d1;Data* p = &d1;

我们需要知道p指向成员变量。

2.3.2小问题

        我们看下面的代码输出结果是什么:

#include<iostream>
using namespace std;
class Data {
public:void Print(){cout << "Print()" << endl;}
};int main()
{Data d1;Data* p = &d1;p->Print();return 0;
}

很显然我们的结果是Print();

那我们的这行代码输出结果是什么呢?

	Data* p = nullptr;p->Print();

 是不是很多人说对空指针的解引用,会导致空指针的解引用,其实这样的结果还是Print(),为什么呢?我们看上面类的成员变量和成员函数是分开的,我们的p是指向我们的成员变量的区域,无论成员变量是什么样子,我们的函数区域是不变的。

	Data* p = nullptr;(*p).Print();

我们这个代码个上面的一样,都会正常运行。 

2.3.3内存对齐

        类的内存对齐和我们在前面c语言中的内存对齐一样,在vs中我们的对齐数为8,我们的Data中_year占0,1,2,3的位置,_month占4,5,6,7,。_day占8,9,10,11占12个12是4的倍数所以占12个,在这里不做具体解释,不理解的可以在内存对齐中查看。

2.3.4内存对齐意义

        我们知道了内存对齐,那它有什莫意义呢?我们这样舍弃空间是为什么呢?我们需要知道一些机器一次只能访问4个或8个字节,我们以4个字节为例,

9ba735349bf34c1aab5e7679c724be85.png

如果我们一次访问4个字节,第一种没有对齐的int需要访问两次,第一期是前三个字节,第二次要访问第4个字节,而第2种我们能访问int能直接进行访问,这样可以减少我们的访问次数,我们采用内存对齐是一种空间换时间的方式,这就是内存对齐的意义。

三.this指针

        this指针是默认生成的,类型为*const 我们不能在形参和实参的位置显示写,但函数种可以用,这是this指针的定义,我们看一看相关代码

#include<iostream>
using namespace std;class A {
public:A(int a = 1){_a = a;}void Print(A*const this){cout << _a << endl;}
private:int _a;
};int main()
{A a;a.Print(this);return 0;
}

我们的代码就会报错,错误如下:

7080d49f9a0944e5961ca134fd39dfc9.png

如果我们将Print函数中加上this呢?

	void Print(){cout <<this-> _a << endl;}

程序就会正常运行。 

四.总结

        今天的内容就结束了,这些都是类的基础,大家可以认真看看,对于后面的内容非常重要。最后希望大家可以一键三连。

 

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

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

相关文章

MacOS - M1芯片 Mac 在“恢复”模式中启用系统扩展教程

部分软件需要开启系统扩展才能正常使用&#xff0c;但是默然M1芯片的Mac不能直接打开系统扩展&#xff0c;如下两图。 若要启用系统扩展&#xff0c;您需要在“恢复”环境中修改安全性设置。 若要执行此操作&#xff0c;请将系统关机&#xff0c;然后按住触控ID或电源按钮以开…

3D裸眼技术行业研究:2026年市场投资规模为10.78亿元

3D裸眼技术大多处于研发阶段&#xff0c;它的研发分两个方向&#xff0c;一是硬件设备的研发&#xff0c;二为显示内容的处理研发。第二种已经开始小范围的商业运用。大众消费者接触的不多。从技术上来看&#xff0c;3D裸眼可分为光屏障式(Barrier)、柱状透镜(Lenticular Lens)…

简单说网络:TCP+UDP

TCP和UPD: (1)都工作在传输层 (2)目的都是在程序之中传输数据 (3)数据可以是文本、视频或者图片(对TCP和UDP来说都是一堆二进制数没有太大区别) 一、区别:一个基于连接一个基于非连接 将人与人之间的通信比喻为进程和进程之前的通信:基本上有两种方式(1)写信;(2)打电话;这…

【Qt】Android上运行keeps stopping, Desktop上正常

文章目录 问题 & 背景背景问题 解决方案One More ThingTake Away 问题 & 背景 背景 在文章【Qt】最详细教程&#xff0c;如何从零配置Qt Android安卓环境中&#xff0c;我们在Qt中配置了安卓开发环境&#xff0c;并且能够正常运行。 但笔者在成功配置并完成上述文章…

C#中使用OpenCvSharp4绘制直线、矩形、圆、文本

C#中使用OpenCvSharp4绘制直线、矩形、圆、文本 继之前的Python中使用Opencv-python库绘制直线、矩形、圆、文本和VC中使用OpenCV绘制直线、矩形、圆和文字&#xff0c;将之前的Python和C示例代码翻译成C#语言&#xff0c;很简单&#xff0c;还是借用OpenCvSharp4库中的Line、…

HarmonyOS SDK 助力新浪新闻打造精致易用的新闻应用

原生智能是HarmonyOS NEXT的核心亮点之一&#xff0c;依托HarmonyOS SDK丰富全面的开放能力&#xff0c;开发者只需通过几行代码&#xff0c;即可快速实现AI功能。新浪新闻作为鸿蒙原生应用开发的先行者之一&#xff0c;从有声资讯入手&#xff0c;基于Speech Kit朗读控件上线听…

cocos creator 3.x 预制体无法显示

双击预制体&#xff0c;进入详情页&#xff0c;没有显示资源 Bomb 是个预制体&#xff0c;但是当我双击进来什么都没有了&#xff0c;无法对预制体进行可视化编辑 目前我只试出来一个解决方法&#xff1a; 把预制体拖进Canvas文件中&#xff0c;这样就能展示到屏幕上&#xff…

在angular12中proxy.conf.json中配置详解

一、proxy.conf.json文件的目录 二、proxy.conf.json文件中的配置 "/xxx/api": {"target": "地址/api","secure": false,"logLevel": "debug","changeOrigin": true,"pathRewrite": {"…

【 buuctf-后门查杀】

采用 D 盾进行扫描查杀 有一个级别为 5 的扫描结果&#xff0c;记事本打开&#xff0c;即为 flag

python算法与数据结构(搜索算法和拓扑排序算法)---广度优先搜索和拓扑排序

广度优先搜索BFS 定义&基本内容 广度优先是按照层次由近及远的进行搜索&#xff0c;在当前层次所有可及节点都搜索完毕后才会继续往下搜索&#xff0c;其本质就是寻找从起点到终点的最短路程。 树的广度优先搜索 树的广度优先遍历&#xff0c;可以看成是层序遍历。 访问…

使用vite创建vue+ts项目,整合常用插件(scss、vue-router、pinia、axios等)和配置

一、检查node版本 指令&#xff1a;node -v 为什么要检查node版本&#xff1f; Vite 需要 Node.js 版本 18&#xff0c;20。然而&#xff0c;有些模板需要依赖更高的 Node 版本才能正常运行&#xff0c;当你的包管理器发出警告时&#xff0c;请注意升级你的 Node 版本。 二、创…

一文学会gtest UT测试编写(TEST\TEST_F)

目录 一、官方文档&代码 二、不同平台导入gtest静态库 Android工程 Linux 三、UT测试 Step by Step 1. 示例入门 2. 断言 EXPECT 与 ASSERT 3. TEST与TEST_F TEST TEST_F 4. gmock Google Test&#xff08;简称 gtest&#xff09;是 Google C 测试框架&#xff0c…