c++--类(上)

news2024/9/20 22:43:41

C++之类(上)

  • 一、类的定义
    • 1.1 类定义格式
    • 1.2 访问限定符
    • 1.3 类域
  • 二、实例化
    • 2.1 实例化的概念
    • 2.2 对象大小
  • 三、this指针

一、类的定义

1.1 类定义格式

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

class stack
{
	int*arr;
	int size;
	int capacity;//成员变量

	void Push(int x);
	int Top();
	void Pop();//成员函数
};

这个就是一个栈的类,它与结构体不同,类是变量与函数不分离。

2、为了区分成员变量,⼀般习惯上成员变量会加⼀个特殊标识,如成员变量前⾯或者后⾯加_ 或者 m开头。

class direction
{
public:
	void Init(int left, int right, int up, int down)
	{
		_left = left;
		_right = right;
		_up = up;
		_down = down;
	}
private:
	//在这里有两种方式可以用来区分
	//1、在成员变量前加_
	//2、用this指针例如(this->left=left)
	int _left;
	int _right;
	int _up;
	int _down;
};

3、 C++中struct也可以定义类,C++兼容C中struct的⽤法,同时struct升级成了类,明显的变化是struct中可以定义函数, ⼀般情况下我们还是推荐⽤class定义类。

struct stack
{
	int*arr;
	int size;
	int capacity;//成员变量

	void Push(int x);
	int Top();
	void Pop();//成员函数
};

这个也是可以的。

4、定义在类⾯的成员函数默认为inline。如果我们不想在类里写我们的函数体,就得用::域作用限定符。

class direction
{
public:
	void Init(int left, int right, int up, int down);
private:
	//在这里有两种方式可以用来区分
	//1、在成员变量前加_
	//2、用this指针例如(this->left=left)
	int _left;
	int _right;
	int _up;
	int _down;
};
void direction::Init(int left, int right, int up, int down)
{
	_left = left;
	_right = right;
	_up = up;
	_down = down;
}

1.2 访问限定符

在这里插入图片描述
1、C++⼀种实现封装的⽅式,⽤类将对象的属性与⽅法结合在⼀块,让对象更加完善,通过访问权限选择性的将其接⼝提供给外部的⽤户使⽤。这里的接口指的就是函数。

2、public修饰的成员在类外可以直接被访问protected和private修饰的成员在类外不能直接被访问,protected和private是⼀样的,在继承章节才会体现它俩的不同。
在这里插入图片描述
大家可以看到size可以轻易的访问,而Top就不能被访问。

3、访问权限作⽤域从该访问限定符出现的位置开始直到下⼀个访问限定符出现时为⽌,如果后⾯没有访问限定符,作⽤域就到 }即类结束。

class stack
{
public:
	int*arr;
	int size;
	int capacity;//成员变量
	//public的范围到private之前
private:
	void Push(int x);
	int Top();
	void Pop();//成员函数
	//后面已经没有访问限定符了,那么private的范围到“}”之前
};

4、class定义成员没有被访问限定符修饰时默认为private,struct默认为public。

5、最后访问限定符可以多次出现,但实际使用一般不这样写。

1.3 类域

类定义了⼀个新的作⽤域,类的所有成员都在类的作⽤域中,在类体外定义成员时,需要使⽤ :: 作⽤域操作符指明成员属于哪个类域。
在这里插入图片描述
特别是这种两个类成员函数名字一样的,一定要指明类域。

二、实例化

2.1 实例化的概念

1、⽤类类型在物理内存中创建对象的过程,称为类实例化出对象。

class direction
{
public:
	void Init(int left, int right, int up, int down);
private:
	//在这里有两种方式可以用来区分
	//1、在成员变量前加_
	//2、用this指针例如(this->left=left)
	int _left;
	int _right;
	int _up;
	int _down;
};
void direction::Init(int left, int right, int up, int down)
{
	_left = left;
	_right = right;
	_up = up;
	_down = down;
}
int main()
{
	direction d1, d2;
	return 0;
}

在这里我们就实例化了两个对象d1,d2。

2、类是对象进⾏⼀种抽象描述,是⼀个模型⼀样的东西,限定了类有哪些成员变量,这些成员变量只是声明,没有分配空间,⽤类实例化出对象时,才会分配空间。
什么意思呢?就是我们定义的类只是一个声明,当我们创建对象,例如上面的d1,d2时才会分配空间。

3、⼀个类可以实例化出多个对象,实例化出的对象 占⽤实际的物理空间,存储类成员变量。
在这里插入图片描述

2.2 对象大小

类实例化出的每个对象,都有独⽴的数据空间,所以对象中肯定包含成员变量,那么成员函数是否包含呢?⾸先函数被编译后是⼀段指令,对象中没办法存储,这些指令存储在⼀个单独的区域(代码段),那么对象中⾮要存储的话,只能是成员函数的指针。
我们只需要记住在算对象大小的时候,不需要计算成员函数,只计算成员变量。
那现在问题来了,要是我们的类里什么都没有,但我们用它实例化了对象,那实例化后的对象的大小是多少啊?
在这里插入图片描述
这⾥给1字节,纯粹是为了占位标识对象存在。

其次我们要算对象的大小我们只需要计算成员变量的大小,其算法与struct的算法一致都是符合内存对齐原则:
在这里插入图片描述
那大家有没有想过为什么要内存对齐啊?
在这里插入图片描述

三、this指针

首先我们先看一个代码:

class direction
{
public:
	void Init(int up, int down, int left, int right)
	{
		_left = left;
		_right = right;
		_up = up;
		_down = down;
	}
public:
	int _left;
	int _right;
	int _up;
	int _down;
};
int main()
{
	direction d1, d2;
	d1.Init(0, 1, 2, 3);
	d2.Init(3, 2, 1, 0);
	cout << d1._up << ' ' << d1._down << ' ' << d1._left << ' ' << d1._right << endl;
	cout << d2._up << ' ' << d2._down << ' ' << d2._left << ' ' << d2._right << endl;
	return 0;
}

为什么这里是同一个函数,打印的确实一样的呢?这里就引入了this指针,this指针通常都是隐含的

那我们将它恢复回原来的样子:

class direction
{
public:
	//void Init(data*const this,int up,int down......)
	void Init(int up, int down, int left, int right)
	{
		this->_left = left;
		this->_right = right;
		this->_up = up;
		this->_down = down;
	}
public:
	int _left;
	int _right;
	int _up;
	int _down;
};
int main()
{
	direction d1, d2;
	d1.Init(0, 1, 2, 3);
	//d1.Init(&d1, 0, 1, 2, 3);
	d2.Init(3, 2, 1, 0);//d2.Init(data* const this,3,2,1,0);
	//d2.Init(&d2, 3, 2, 1, 0);
	cout << d1._up << ' ' << d1._down << ' ' << d1._left << ' ' << d1._right << endl;
	cout << d2._up << ' ' << d2._down << ' ' << d2._left << ' ' << d2._right << endl;
	return 0;
}

需要注意的是:C++规定不能在实参和形参的位置显⽰的写this指针(编译时编译器会处理),但是可以在函数体内显⽰使⽤this指针。

最后我们需要知道this指针存在于哪个区域,是堆、栈,还是常量区还是对象里?

我们要知道this指针是作为形参传递的对不对,形参存储于栈里,所以在这里栈比较合适,但是由于c++里经常使用this指针,所以有些编译器会将其放入寄存器,但是在做题过程中我们选栈。

这两个题目有助于我们理解this指针,大家可以简单的看下

1、问它运行结果是什么?

#include<iostream>
using namespace std;
class A
{
public:
	void Print()
	{
		cout << "A::Print()" << endl;
	}
private:
	int _a;
};

int main()
{
	A* p = nullptr;
	p->Print();
	return 0;
}
//A、编译报错 B、运⾏崩溃 C、正常运⾏

这个题目选择正常运行,虽然这里p是空指针,但我们这里是将它的地址作为参数传递,成员函数不存于类的变量中,我们访问成员函数并没有通过this指针。
在这里插入图片描述

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

而在这里我们使用了_a这个成员变量,这里解引用了空指针,所以这里运行崩溃。

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

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

相关文章

Ollama - Llama3 docker版本安装部署使用

项目地址&#xff1a;https://github.com/meta-llama/llama3 Meta 发布两款开源Llama 3 8B与Llama 3 70B模型&#xff0c;供外部开发者免费使用。Llama 3的这两个版本&#xff0c;也将很快登陆主要的云供应商。 按照Meta的说法&#xff0c;Llama 3 8B和Llama 3 70B是目前同体量…

threejs中实现物体阴影

在Three.js中实现阴影需要几个步骤&#xff0c;包括设置渲染器、光源以及物体的材质等。以下是一个基本的实现阴影的步骤&#xff1a; 1、设置渲染器以支持阴影&#xff1a; const renderer new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerH…

三大运营管理平台:打造智能化新能源数据管理的核心利器

随着全球能源结构的转型和新能源技术的快速发展&#xff0c;智能化新能源数据管理成为行业发展的关键。三大运营管理平台的出现&#xff0c;正是为了解决这一需求&#xff0c;它们通过整合先进的信息技术和智能算法&#xff0c;为新能源企业提供了全面、高效、精准的数据管理解…

告别帕金森手抖,这些维生素是你的秘密武器!

亲们&#xff0c;你们有没有遇到过这样的情况&#xff1f;家里的长辈或是自己&#xff0c;偶尔会出现手不自觉颤抖的现象&#xff0c;特别是被诊断为帕金森病的朋友&#xff0c;更是深受其扰。&#x1f614; 别担心&#xff0c;今天就来聊聊如何通过科学补充一些关键维生素&…

函数:02

1.三角函数 名称表达式正弦sinx b r \frac{b}{r} rb​余弦cosx a r \frac{a}{r} ra​正切tanx b a \frac{b}{a} ab​余切cotx a b \frac{a}{b} ba​正割secx r a \frac{r}{a} ar​余割cotx r b \frac{r}{b} br​ 1.1用正弦&#xff0c;余弦函数表示正/余切&#xff0c;正/余割…

Web大学生网页作业成品——保护环境环保介绍网页设计与实现(HTML+CSS)(1个页面)

&#x1f389;&#x1f389;&#x1f389; 常见网页设计作业题材有**汽车、环保、明星、文化、国家、抗疫、景点、人物、体育、植物、公益、图书、节日、游戏、商城、旅游、家乡、学校、电影、动漫、非遗、动物、个人、企业、美食、婚纱、其他**等网页设计题目, 可满足大学生网…

20221元组

在Python语言中, (7)是一种可变的、有序的序列结构,其中元素可以重复。 A.元组(tuple) B. 字符串(str) C. 列表(list) D.集合(set) ChatGPT 说&#xff1a; ChatGPT 在Python中&#xff0c;选项 C 列表(list) 符合题目描述。 解释&#xff1a; 列表 (list) 是一种可变的、有…

OOP篇(Java - 思维逻辑练习)(doing)

目录 一、继承 1. 简介 2. 表现形式 2.1. 电脑的表现形式 2.2. 程序的表现形式 资料库 课程 课程放入到资料库 视频资源 资源库 存在问题 如何解决问题 3. 继承 定义父类 课程类继承 视频类继承item 资源库类2 整个的继承关系 4. 通过继承得到了什么&#x…

基于spring boot的酒店管理系统

获取源码联系方式请查看文章结尾&#x1f345; 目 录 基于spying boot的酒店管理系统 ABSTRACT 第一章 绪论 1.1课题背景 1.2研究意义 1.3研究内容 第二章 技术介绍 2.1相关技术 2.2java技术 2.3MySQL数据库 2.4 Tomcat介绍 2.5 SSM框架 第3章 需求分析 3.1需求分…

水文仪器设备

水文仪器设备可以监测水位、雨量、流速、流量等水文要素。这些设备使用各种传感技术和测量原理来获取准确的数据。以下是常见的水文仪器设备&#xff1a; 水位计&#xff1a;用来测量水位高度的仪器。常见的水位计有浮标式水位计、压力式水位计、超声波水位计等。 雨量计&…

Redis大显身手:实时用户活跃排行榜

文章目录 场景说明方案设计数据结构 Redis使用方案排行榜实现更新用户活跃积分幂等策略榜单评分更新触发活跃度更新排行榜查询 技术派项目源码地址 : Gitee :技术派 - https://gitee.com/itwanger/paicodingGithub :技术派 - https://github.com/itwanger/paicoding 效果如图 …

maven项目的目录结构

今天用jdk17创建maven项目时候出的问题 那就一步步自己整了 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schema…

车载以太网AVB系统方案搭建基于100BASE-T1车载以太网

1.音频传输系统需求 音频是智能座舱的核心功能&#xff0c;涵盖车载音响、语音识别、e-Call、消噪及回声消除等应用&#xff0c;随着汽车智能网联化的发展&#xff0c;对音频的开发要求也越来越高。传统的车载音频系统采用模拟并行音频信号传输方式&#xff0c;难以在功能增加…

RabbitMQ消息持久化实现

RabbitMQ消息持久化实现 1. 交换器的持久化2. 队列的持久化3. 消息的持久化 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; RabbitMQ作为流行的消息队列&#xff08;MQ&#xff09;产品&#xff0c;提供了全面的持久化机制&#xff0c;确保…

Leetcode每日刷题之209.长度最小的子数组(C++)

1.题目解析 根据题目我们知道所给的数组均是正整数&#xff0c;我们需要找到的是该数组的子数组&#xff0c;使其子数组内所有元素之和大于或等于给出的目标数字target&#xff0c;然后返回其长度&#xff0c;最终找出所以满足条件的子数组&#xff0c;并且要返回长度最小的子数…

【Redis分析】(二) Sentinel

哨兵 - 高可用 哨兵&#xff08;Sentinel&#xff09; 是 Redis 的高可用性解决方案&#xff1a;由一个或多个 Sentinel 实例组成的 Sentinel 系统可以监视任意多个主服务器&#xff0c;以及这些主服务器属下的所有从服务器。 Sentinel 可以在被监视的主服务器进入下线状态时…

mysql windows安装与远程连接配置

安装包在主页资源中 一、安装(此安装教程为“mysql-installer-community-5.7.41.0.msi”安装教程&#xff0c;安装到win10环境) 保持默认选项&#xff0c;点击”Next“。 点开第一行加号展开一路展开找到“MySQL Server 5,7,41 - X64”点击选中点击一下中间只想右侧的箭头看到…

encoding with ‘idna‘ codec failed (UnicodeError: label empty or too long)

今天在使用Flask连接mysql的时候&#xff0c;遇到了一个报错&#xff1a;encoding with ‘idna’ codec failed (UnicodeError: label empty or too long) 网上查了一下说是字符集的问题&#xff0c;然后尝试修改了一下字符集&#xff0c;结果还是不行。 最后去翻阅SQLAlchemy…

AI时代的学术写作:Kimi如何助力文献综述?

在学术研究的浩瀚海洋中&#xff0c;文献综述无疑是探索知识边界的重要工具。它不仅是对现有研究的梳理&#xff0c;更是对未来研究方向的指引。然而&#xff0c;撰写一篇高质量的文献综述并非易事&#xff0c;它要求研究者具备广泛的文献检索能力、深刻的分析批判能力以及严谨…

基于springboot的城市垃圾分类管理系统--论文pf

TOC springboot487基于springboot的城市垃圾分类管理系统--论文pf 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进…