C++类和对象1:类是什么?对象是什么?

news2024/11/18 4:28:39

 

目录

类的引入

类的定义

类的定义规则

 类域问题:

 类的访问限定符及封装

访问限定符

 封装

类的实例化

类对象的大小问题

 this指针

 This指针的一些特性:


类的引入

 在学习C语言的时候,C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题

自然而然的,C语言就不需要高集成度的结构,每个类型的功能比较单一,比如结构体,在C语言下只能存放各类其他的类型,有函数需要的时候就拿来用就好,这种运作逻辑有点像锤子和钉子。

我们的问题是如何把钉子钉到木板里,我们用锤子把钉子钉入木板的方法就像函数,锤子和钉子就像是各种变量,他们之间的关系较为独立。


而C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完
成。拿钉钉子这个过程举例子,如果C语言是简单的锤子钉钉子,那么C++就是直接拿着钉枪开始钉了。

 那么也就意味着,我们不需要关注钉枪是怎么运作的,拿起来就好,也就是我们不再需要一个函数来指导我们怎么钉钉子,钉枪如何运作则是这个对象的事情。那么钉枪内部运作需要很多的电子原件,里面只有锤子可不行,还需要有更多的功能,那么我们该如何包装这个“钉枪”呢?于是,类就出现了。

类的定义

 class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分
号不能省略。
类体中内容称为类的成员:类中的变量称为类的属性成员变量; 类中的函数称为类的方法或者
成员函数。

class className
{
    // 类体:由成员函数和成员变量组成
}; // 一定要注意后面的分号

用C语言方式实现的栈,结构体中只能定义变量;现在以C++方式实现,会发现struct中也可以定义函数,那么我们就可以一股脑的往里头放

typedef int Stackdatatype;
class Mystack
{
public:
	Mystack()
		:_a(nullptr)
		,_top(0)
		,_capacity(0)
	{}

	void Push(int x)
	{
		if (_top == _capacity)
		{
			int newcapacity = _capacity == 0 ? 4:_capacity*2;
			Stackdatatype* tmp =(Stackdatatype*)realloc(_a, newcapacity * sizeof(Stackdatatype));
			_a = tmp;
			_capacity = newcapacity;
		}

		_a[_top] = x;
		++_top;
	}

	void PrintStack()
	{
		for (int i = 0; i < _top; ++i)
			cout << _a[i] << endl;
	}

	Stackdatatype StackTop()
	{
		return _a[_top-1];
	}


private:
	Stackdatatype* _a;
	int _top;
	int _capacity;

};

然后用起来试试看

 那么这就很爽了,我们使用栈的时候不再需要创建一大堆的函数,直接拿过来用就可以了。

当然其中还有不少的细节,我们之后一一来看,现在我们先初步了解类的定义规则。


类的定义规则

第一种:声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。

 2. 类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名::

 类域问题:

声明于定义分离是我们常玩的东西了,不仅可以增加代码的可读性,也让我们管理变得方便不少,但是有一个问题,当定义与声明分离时,我们怎么知道当前定义的是哪个函数呢?

比如栈和队列都有一个叫Init的函数,我们编写定义的时候怎么区分他俩?

class Stack
{
    void Init();
    ....
};

class Queue
{
    void Init();
    ....
};

这个时候需要使用到上一篇文章中的域作用限定符::来指定当前定义的成员函数属于哪个类

void Stack::Init()
{
    ...
}


void Queue::Init()
{
    ...
}

 类的访问限定符及封装

最开始接触类的时候,我们肯定会对这两个东西产生疑问

 这两个东西叫访问限定符,这两个限定符有什么功能?

访问限定符

C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选
择性的将其接口提供给外部的用户使用

【访问限定符说明】
1. public修饰的成员在类外可以直接被访问
2. protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
4. 如果后面没有访问限定符,作用域就到 } 即类结束。
5. class的默认访问权限为private,struct为public(因为struct要兼容C)

那么C++中struct和class的区别是什么?

C++需要兼容C语言,所以C++中struct可以当成结构体使用。另外C++中struct还可以用来
定义类。和class定义类是一样的,区别是struct定义的类默认访问权限是publicclass定义的类默认访问权限是private。


 封装

C++之所以使用访问限定符,是为了封装,封装可以让我们的程序可以在更加安全的应用场景下减少出现BUG的几率。

具体的情况举个例子,一台洗衣机的功能使其涉及的按钮并不多,其中内部的电路板以及电子元件单片机什么的都被包装起来了,不去暴力破拆很难看见,毕竟没有必要,而且也能保证用户不会误触某些原件造成短路,封装的本意也是如此,保护成员变量,保证其不被修改并运行于理想状态。

在C++语言中实现封装,可以通过类将数据以及操作数据的方法进行有机结合,通过访问权限来
隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用


类的实例化

 用类类型创建对象的过程,称为类的实例化

如上所展示的结构栈的类的实现,其中main函数内部的这串代码创建了名为St的对象,这个对象是以MyStack类实例化出来的

int main()
{
    MyStack St;
}

这个过程简而言之类似照着配方做蛋糕的过程,类的创建就像是配方,类的实例化则是就着配方制作出蛋糕。

一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,才存储类成员变量


类对象的大小问题

 那么类对象的大小是多少呢?我们还是拿上面的栈试试

 啥?为啥是两个12呢?我类里面的函数为什么不计算入大小?

因为类的存储模型只存储类内部的变量,函数是不存储的,我们对函数的存储提出两种猜想:

1.存储的是函数的指针。我们先前已经看过,打印类和类对象的大小都是成员变量的大小,函数指针本身也需要空间存放,所以不太可能

2.所有的类成员函数被存储到了类成员函数表内。

先记录一个问题:

那为什么不把函数和变量放一块呢?这样不是很方便吗?

我们使用某一个类如果将函数和变量都存放在一块的话,假如这个类被多次生成类对象将会产生非常多重复空间的浪费。毕竟某一些对象可能完全用不着其他的成员函数。

成员函数存放在公共代码段

成员函数如果存储在公共代码段将会是非常不错的存储方式,按需索取,不会产生空间上的浪费我们只需要当调用函数的时候去函数表里头找就行了。

那么只存了一个函数的类的对象的大小时多少?0吗?

 其实是1,这个1其实是占位符,不存储有效数据,标识对象存在。


 this指针

 虽然我们知道编译器使用函数的时候用的是公共代码段,那么为什么对象不一样,函数输出也不一样?

隐藏的this指针就是原因,谁调用,谁访问这个函数,谁就把自己对象的成员传进去

this指针本身指向的是当前调用函数的对象,它的指针类型是当前存在的类的类型

 This指针的一些特性:

 被隐藏的This指针长这样

void Func(class* const this)

 特性:

1.this指针自己本身是携带一个const的,所以我们无法直接对this指针进行赋值。(当const在*左边的时候,保护的是指针所指向的对象,而在*右边的时候保护的是指针本身。)

2.this指针是作为传递成员函数的形参而存在的,所以对象中不能存储this指针。

3.this指针只能在成员函数内使用。

4.作为一个隐藏的形参,我们不需要去传递对应的实参,寄存器会帮助我们完成这项工作。

这也解释了为什么我们不能直接访问类内部的函数,因为其内部的函数接收的参数只是类生成对象的指针!如果你想强行使用里面的函数那你连传什么都不知道。

5.this指针的定义和传递都是编译器的活儿,我们不能去抢,但是我们可以用

补充:This指针在所有的成员函数里都有

 两道面试题:

1.This指针存在哪?

我们可能会想当然的觉得this指针存放在对象内部,但其实它存放在栈内部,因为它是形参具有栈帧

举例:

 如图所示的一个成员函数,它的形参其实有4个,还包含了一个被隐藏的this指针。

2.下面两道题的答案是什么?为什么?

答案是B,C,原因如下:

我们先再次的复习一遍概念:this指针调用的原则是:谁调用,谁访问这个函数,谁就把自己对象的成员传进去

  到这里,类和对象还有this指针最最基本的概念就解释完毕了!希望对你有点帮助!感谢阅读!

但这都还没有结束!接下来则是构造函数了!

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

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

相关文章

2023年5月北京老博会,医养家具展,护理床展,老年护理展

2023中国国际养老服务业博览会CISSE介绍&#xff1a; 2023中国国际养老服务业博览会&#xff08;CISSE&#xff09;将于5月5-7日在北京国家会议中心举行。大会以养老产业为主题&#xff0c;通过展贸平台为涉老企业抢占市场先机&#xff0c;对企业营销策略、宣传影响力、定位产品…

apt-fast 使用

apt-fast 使用1. 安装2. 使用默认的apt-get install&#xff0c;有时下载会非常的慢&#xff0c;尤其是安装的一些ppa包的时候。apt-fast 通过使用多线程来给apt提速&#xff0c;极大地提高了效率。 1. 安装 添加ppa仓库 sudo add-apt-repository ppa:apt-fast/stable 更新软…

CAPL学习之路-测试功能集函数(约束和条件)

在test module和test unit中,可以添加事件对象或事件文本作为条件或约束。当事件发生时,条件或约束受损,测试报告中输出“Fail”条目,同时测试用例判定为“Fail” 此类函数有: TestAddCondition/TestAddConstraint,添加事件对象或事件文本作为条件或约束。不管是作为条件…

傻白入门芯片设计,如何写一篇好文章(十八)

目录 一、标题Title 如何看浩如烟海的文献&#xff1f; 二、摘要Abstract 三、介绍Introduction &#xff08;1&#xff09;“六句扩展法” &#xff08;2&#xff09;常见的逻辑&#xff1a; &#xff08;3&#xff09;更好的逻辑&#xff1a; 四、相关工作Related wo…

《CSAPP》笔记——系统级IO、网络编程、并发编程

文章目录传送门系统级IOUnix输入和输出Unix文件Unix文件操作Unix管理打开文件打开文件流程文件共享重定向文件标准IO标准IO流标准IO的缓冲机制RIO&#xff08;Robust IO&#xff09;对比与总结网络编程历史从头构建互联网网络层次以太网段网桥连接的以太网段互联网网络协议互联…

远程代码执行渗透与攻防(一)

目录 前言 远程代码执行&#xff1a;Remote Code Execute 远程命令执行&#xff1a;Remote Command Execute 为什么要远程执行代码&#xff1f; 漏洞危害 近几年影响比较大的RCE漏洞 PHP RCE涉及函数 代码code注入&#xff1a; 命令command注入 &#xff1a; 靶场案…

Word控件Spire.Doc 【评论】教程(4):C#、VB.NET如何在Word的评论中插入图片

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…

认真学习MySQL中锁机制(二)

接上文认真学习MySQL中锁机制&#xff08;一&#xff09;我们继续学习MySQL中的锁机制。 【5】按加锁的方式划分&#xff1a;显示锁、隐式锁 ① 隐式锁 一个事务在执行insert操作时&#xff0c;如果即将插入的间隙已经被其他事务加了gap锁&#xff0c;那么本次insert操作会阻…

分类算法KNN的python实现

作者&#xff1a;刘凡 KNN算法介绍 KNN算法是有监督学习中的分类算法&#xff0c;它是一种非参的&#xff0c;惰性的算法模型。非参的意思并不是说这个算法不需要参数&#xff0c;而是意味着这个模型不会对数据做出任何的假设&#xff0c;与之相对的是线性回归&#xff08;我…

隐语任务调度

隐语目前暂定支持的设备列表&#xff1a; 一 PYU 数据所有者是SecretFlow中的PYU设备&#xff0c;明文并成为PYU Objects一个PYU object&#xff08;明文&#xff09;可以被转化为秘密分享&#xff0c;被叫做SPU Object。Python函数可以被发送至SPU设备执行&#xff0c;背后是…

人工智能:图像数字化相关的知识介绍

❤️作者主页&#xff1a;IT技术分享社区 ❤️作者简介&#xff1a;大家好,我是IT技术分享社区的博主&#xff0c;从事C#、Java开发九年&#xff0c;对数据库、C#、Java、前端、运维、电脑技巧等经验丰富。 ❤️个人荣誉&#xff1a; 数据库领域优质创作者&#x1f3c6;&#x…

只从 2022 年算起,谷歌就向社会输送了至少 26 位高端 AI 人才。

2022 年&#xff0c;人工智能在 AIGC、AI for science 等领域持续发展&#xff0c;一些工作也在知识型模型方面做出了探索。除了这些研究成果&#xff0c;我们还会发现这一年人工智能从业者的工作情况也有比较大的变化。 例如&#xff0c;Meta 等大型科技公司进行了大规模的裁…

【 shell 编程 】第1篇 变量

变量 文章目录变量一、前言二、变量1.变量的类型2.变量的运算一、前言 1.什么是 shell 简介&#xff1a; SHELL是UNIX系统的用户与操作系统之间的一种接口。它既是UNIX系统的命令解释程序&#xff0c;又是一种高级的命令程序设计语言。 作为命令解释程序&#xff0c;SHELL接收…

Windows/Mac/Ubuntu环境下安装Dokcer

前提概要&#xff1a; 注意&#xff1a;安装虚拟环境的步骤我放到另外一个文章里面啦&#xff0c;有需要的可以看看哦 Docker介绍&#xff1a;1、Docker 并⾮是⼀个通⽤的容器⼯具&#xff0c;它依赖于已存在并运⾏的 Linux 内核环境。2、Docker 实质上是在已经运⾏的 Linux 下…

智慧养老系统(社区+居家+机构养老)

智慧养老是一个新的养老模式&#xff0c;信息化医疗服务&#xff0c;不仅能够提高养老产业的质量&#xff0c;提高养老成本降低&#xff0c;而且能够提高老人的身体健康&#xff0c;提高养老人的老年生活质量。 智慧养老系统解决方案提供完整的机构养老系统、社区养老系统&…

在项目中使用——newFixedThreadPool线程池

newFixedThreadPool线程池前言newFixedThreadPool的介绍使用newFixedThreadPool的步骤实例化一个固定线程大小线程池创建一个用于启动新线程的类使用submit提交线程最后关闭关闭线程池CountDownLatch配合线程池使用构造CountDownLatch计数器减一使调用该方法的线程处于等待状态…

推荐 12 月 yyds 的开源项目

本期推荐开源项目目录&#xff1a;1. 面向 API 的低代码平台2. 京东抢购自动下单助手3. 开发人员使用的低代码平台4. 好用又强大的开源建站工具5. OCR 图片转文字识别软件6. 互联网仍有记忆01面向 API 的低代码平台APITable 一个面向 API 的低代码平台&#xff0c;用于构建协作…

推荐系统从入门到入门(2)——简单推荐系统构建(无框架、Tensorflow)

本系列博客总结了不同框架、不同算法、不同界面的推荐系统&#xff0c;完整阅读需要大量时间&#xff08;又臭又长&#xff09;&#xff0c;建议根据目录选择需要的内容查看&#xff0c;欢迎讨论与指出问题。 系列文章梗概 本次大作业主要是以电影推荐系统为例&#xff0c;介绍…

GIC V3 V4 逻辑组件

GIC V3 & V4 逻辑组件1 GIC V3逻辑组件2 GIC 各组件的介绍2.1 Distributor2.2 Interrupt translation service, ITS2.3 Redistributor2.4 CPU interface1 GIC V3逻辑组件 The GICv3 architecture consists of a set of logical components: • A Distributor.• A Redist…

C++ 实现Manacher算法

前言 Manacher算法是一种回文串查找算法&#xff0c;专门用于处理查找字符串中的回文子串操作。虽然这个算法本身只是用于查找回文子串&#xff0c;但是它的查找思想还是非常值得学习的。由于Manacher算法是基于暴力解法优化而来的&#xff0c;所以在阅读正式的算法之前&#…