【C++】类和对象--类,实例化,this指针

news2024/9/22 5:41:09

文章目录

  • 前言
  • 一、类
    • 1.1 类的定义
    • 1.2 类的书写和使用
    • 1.3 访问限定符
    • 1.4 类域
  • 二、实例化
    • 2.1 实例化概念
    • 2.2 对象大小
  • 三.this指针
  • 总结


在这里插入图片描述

前言

前面的几篇文章我们介绍了命名空间,inline,nullptr等C++
中常见的的基础概念。今天的文章我们来介绍一些C++中类与对象的内容。


一、类

1.1 类的定义

在现实世界中,经常有属于同一类的对象。例如,你的自行车只是世界上很多自行车中的一辆。在面向对象软件中,也有很多共享相同特征的不同的对象:矩形、雇用记录、视频剪辑等。可以利用这些对象的相同特征为它们建立一个集合。而这个集合就称为类。类是定义同一类所有对象的变量和方法的蓝图或原型。

1.2 类的书写和使用

class Stack
{
public:
	void Init(int n=4)
	{
		int* tmp = (int*)malloc(sizeof(int) * n);
		if (tmp == NULL)
		{
			perror("malloc");
			return;
		}
		a = tmp;
		size = top = 0;
	}
	void Push(int x)
	{
		if (top == size)
		{
			int newsize = size * 2;
			int* tmp = (int*)realloc(a, sizeof(int) * newsize);
			if (tmp == NULL)
			{
				perror("realloc");
				return;
			}
			a = tmp;
		}
		a[top] = x;
		top++;
	}
private:
	int* a;
	int top;
	int size;
};

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

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

在定义类的成员名称时,为了与函数的形参区分,一般会在变量名前面加上"_"或者m,这个在C++标准中并没有明确规定,根据实际需求使用。

struct ListNodeCPP
{
 void Init(int x)
 {
 next = nullptr;
 val = x;
 }
 ListNodeCPP* next;
 int val;
};

C++中的结构体也可以定义类,C++中兼容C的结构体并将其升级为类。在结构体内部也可以定义函数。并且在C++中结构体的名字直接可以作为类型名,这就省去了我们通过typedef简化掉struct的过程。但是我们还是推荐使用class来定义类。

在类中定义的函数的类型默认为inline。

1.3 访问限定符

在上面的Stack类中,我们发现有public和private这两个单词。这就是访问限定符。访问限定符有三个
在这里插入图片描述
• 这是C++⼀种实现封装的方式,用类将对象的属性与方法结合在⼀块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。

• public修饰的成员在类外可以直接被访问;protected和private修饰的成员在类外不能直接被访问,protected和private是⼀样的,在以后继承的内容中才能体现出他们的区别。

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

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

• ⼀般成员变量都会被限制为private/protected,需要给别人使用的成员函数会放为public。

•在一个类中可以有多个public,private等限制符,但是方便起见,我们一般把他们放在一起。

1.4 类域

  • 类定义了⼀个新的作用域,类的所有成员都在类的作用域中,在类体外定义成员时,需要使用::作用域操作符指明成员属于哪个类域。
  • 类域影响的是编译的查找规则,下面程序中Init如果不指定类域Stack,那么编译器就把Init当成全局函数,那么编译时,找不到数组a等成员的声明/定义在哪里,就会报错。指定类域Stack,就是知道Init是成员函数,当前域找不到的a等成员,就会到类域中去查找。
class Stack
{
public:
	void Init(int n = 4);
private:
	int* a;
	size_t capacity;
	size_t top;
};
// 声明和定义分离,需要指定类域
void Stack::Init(int n)
{
	a = (int*)malloc(sizeof(int) * n);
	if (nullptr == a)
	{
		perror("malloc申请空间失败");
		return;
	}
	capacity = n;
	top = 0;
}

二、实例化

2.1 实例化概念

⽤类类型在物理内存中创建对象的过程,称为类实例化出对象。我们创建出一个类,相当于画出了一个图纸,我们通过这个图纸建造出的房屋就是实例。所以实例化就是从图纸到房屋的过程。我们只定义出一个类,它是不用空间,只有将它实例化后才会开辟空间。
在这里插入图片描述

2.2 对象大小

首先我们先来分析一下类对象中有哪些成员?成员函数+成员变量。类实例化后的每个对象都有独立的数据空间,所以成员变量是要占据一定空间的。那么成员函数是否占用空间呢?首先函数被编译后是一段指令,对象中无法存储,这些指令存储在一个单独的区域(代码段),如果对象中想要存储他,就只能存储成员函数的指针。我们在分析一下,每一个实例的成员变量都有自己的空间是因为,每一个实例的变量可能不同所以单独存储,但是每一个实例中的成员函数的指针是一样的,如果每实例化一个对象都开辟空间就会产生浪费。所以成员函数是不储存在对象内的。其实函数指针不需要存储,函数指针是一个地址,调用函数被编译成汇编指
令[call地址],其实编译器在编译链接时,就要找到函数的地址,不是在运行时找,只有动态多态是在运行时找,就需要存储函数地址。

上面我们分析了对象中只存储成员变量,C++规定类实例化的对象也要符合内存对齐的规则。

内存对齐规则
• 第⼀个成员在与结构体偏移量为0的地址处。
• 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
• 注意:对齐数=编译器默认的⼀个对齐数与该成员大小的较小值。
• VS中默认的对齐数为8
• 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
• 如果嵌套了结构体的情况,嵌套的结构体对齐到在自己的最大对齐数的整数倍处,结构体的整体大小
就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

我们再来看一段代码,思考它的结果是什么

class A
{
public:
	void Print()
	{
		//...
	}
};
class B
{};
int main()
{
	A b;
	B c;
	cout << sizeof(b) << endl;
	cout << sizeof(c) << endl;
	return 0;
}

在这里插入图片描述
上面的程序运行后,我们看到没有成员变量的B和C类对象的大小是1,为什么没有成员变量还要给1个字节呢?因为如果⼀个字节都不给,怎么表示对象存在过呢?所以这里给1字节,纯粹是为了占位标识对象存在。

三.this指针

this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。也就是说,即使你没有写上this指针,编译器在编译的时候也是加上this的,它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行。

例如,调用date.SetMonth(9) <===> SetMonth(&date, 9),this帮助完成了这一转换 .

class Date
{
public:
	// void Init(Date* const this, int year, int month, int day)
	void Init(int year, int month, int day)
	{
		// this->_year = year;
		_year = year;
		this->_month = month;
		this->_day = day;
	}
	void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

this指针是类的一个自动生成、自动隐藏的私有成员,它存在于类的非静态成员函数中,指向被调用函数所在的对象。全局仅有一个this指针,当一个对象被创建时,this指针就存放指向对象数据的首地址。

关于this指针的一个经典回答:
当你进入一个房子后,
你可以看见桌子、椅子、地板等,
但是房子你是看不到全貌了。
对于一个类的实例来说,
你可以看到它的成员函数、成员变量,
但是实例本身呢?
this是一个指针,它时时刻刻指向你这个实例本身


总结

以上就是今天的全部内容,主要介绍了一些C++的基础内容,C++的内容还有许多,如果喜欢这篇博客,期待你的一键三连。

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

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

相关文章

一款24小时实时检测的六氟化硫气体泄漏报警系统

尽管当前工业生产模式越来越趋于自动化、智能化&#xff0c;但安全生产仍然是时下屡被提及的话题。在配电室等使用六氟化硫气体的众多领域中&#xff0c;由于气体泄漏而引发的中毒、火灾、爆炸、窒息事故仍高发频发。因此&#xff0c;安装六氟化硫气体泄漏报警监测系统仍是企业…

使用PEFT库进行ChatGLM3-6B模型的QLORA高效微调

PEFT库进行ChatGLM3-6B模型QLORA高效微调 QLORA微调ChatGLM3-6B模型安装相关库使用ChatGLM3-6B模型GPU显存占用准备数据集加载数据集数据处理数据集处理加载量化模型-4bit预处理量化模型配置LoRA适配器训练超参数配置开始训练保存LoRA模型模型推理合并模型使用微调后的模型 QLO…

UE5 本地化多语言方案

导入插件&#xff1a; https://www.unrealengine.com/marketplace/zh-CN/product/07e1d9bd9ced444c9b2a7e232161f74d​www.unrealengine.com/marketplace/zh-CN/product/07e1d9bd9ced444c9b2a7e232161f74d 打开测试关卡 打开插件下图目录&#xff0c;csv文件可以添加多个&…

MD5加密和注册页面的编写

MD5加密 1.导入包 npm install --save ts-md5 2.使用方式 import { Md5 } from ts-md5; //md5加密后的密码 const md5PwdMd5.hashStr("123456").toUpperCase(); 遇见的问题及用到的技术 注册页面 register.vue代码 <template><div class"wappe…

模型评估、交叉验证

目录 一、模型评估&#xff1a;二、交叉验证&#xff1a; 一、模型评估&#xff1a; 模型评估用来检验模型的预测精度。 首先数据集分为训练集和测试集两部分&#xff0c;使用训练集进行模型的训练&#xff0c;使用测试集进行模型的评估。 注意&#xff0c;模型评估阶段应该…

A股强反之后继续下单,难道是主力再使障眼法?

今天的A股太不对劲了&#xff0c;主力再使障眼法&#xff0c;很多散户都被成功迷惑&#xff0c;市场有望出现芙蓉出水&#xff0c;不废话&#xff0c;直奔主题&#xff1a; 1、今天两市低开再次探底&#xff0c;太不对劲了&#xff0c;昨天主力大幅流入&#xff0c;今天又跑了…

IT入门知识第十部分《IT职业发展》(10/10)

IT职业发展的深度解析&#xff1a;技能、路径与规划 在当今这个快速发展的数字化时代&#xff0c;IT行业不仅是技术革新的前沿阵地&#xff0c;也是职业发展和个人成长的沃土。本文将深入探讨IT行业的职业发展&#xff0c;包括职业路径的选择、技能提升的策略、以及职业规划的…

FastAPI 学习之路(三十七)元数据和文档 URL

实现前的效果 那么如何实现呢&#xff0c;第一种方式如下&#xff1a; from routers.items import item_router from routers.users import user_router""" 自定义FastApi应用中的元数据配置Title&#xff1a;在 OpenAPI 和自动 API 文档用户界面中作为 API 的…

迅为3A5000LoongArch架构核心主板支持国产麒麟、统信、以及实时系统翼辉SylixOS

性能强 采用全国产龙芯3A5000处理器&#xff0c;基于龙芯自主指令系统 (LoongArch)的LA464微结构&#xff0c;并进一步提升频率&#xff0c;降低功耗&#xff0c;优化性能。 桥片 采用龙芯 7A2000&#xff0c;支持PCIE 3.0、USB 3.0和 SATA 3.0.显示接口2 路、HDMI 和1路 VGA&a…

昆法尔The Quinfall在Steam上怎么搜索 Steam上叫什么名字

昆法尔The Quinfall是一款全新的MMORPG&#xff0c;在中世纪的深处&#xff0c;参与独特的战斗和沉浸式的故事&#xff0c;有几十个不同的职业。而游戏中的战斗系统更是丰富多彩&#xff0c;无论是陆地激战、海上鏖战还是城堡围攻&#xff0c;都能让玩家感受到前所未有的刺激和…

pytorch实现水果2分类(蓝莓,苹果)

1.数据集的路径&#xff0c;结构 dataset.py 目的&#xff1a; 输入&#xff1a;没有输入&#xff0c;路径是写死了的。 输出&#xff1a;返回的是一个对象&#xff0c;里面有self.data。self.data是一个列表&#xff0c;里面是&#xff08;图片路径.jpg&#xff0c;标签&…

如何分辨AI生成的内容?AI生成内容检测工具对比实验

检测人工智能生成的文本对各个领域的组织都提出了挑战&#xff0c;包括学术界和新闻界等。生成式AI与大语言模型根据短描述来进行内容生成的能力&#xff0c;产生了一个问题&#xff1a;这篇文章/内容/作业/图像到底是由人类创作的&#xff0c;还是AI创作的&#xff1f;虽然 LL…

【数据库】Redis主从复制、哨兵模式、集群

目录 一、Redis的主从复制 1.1 主从复制的架构 1.2 主从复制的作用 1.3 注意事项 1.4 主从复制用到的命令 1.5 主从复制流程 1.6 主从复制实现 1.7 结束主从复制 1.8 主从复制优化配置 二、哨兵模式 2.1 哨兵模式原理 2.2 哨兵的三个定时任务 2.3 哨兵的结构 2.4 哨…

MT3047 区间最大值

思路&#xff1a; 使用哈希表map和set&#xff08;去重&#xff09;维护序列 代码&#xff1a; #include <bits/stdc.h> using namespace std; const int N 1e5 10; int n, k, A[N]; map<int, int> mp; // 元素出现的次数 set<int> s; // 维护出现…

Android平台GB28181记录仪在电网巡检抢修中的应用和技术实现

技术背景 在探讨Android平台GB28181设备接入端在电网巡检抢修优势之前&#xff0c;我们已经在执法记录仪、智能安全帽、智能监控、智慧零售、智慧教育、远程办公、明厨亮灶、智慧交通、智慧工地、雪亮工程、平安乡村、生产运输、车载终端等场景有了丰富的经验积累&#xff0c;…

linux创建定时任务

crontab方式 先查看是否有cron systemctl status crond 没有的话就安装 yum install cronie 打开你的crontab文件进行编辑。使用以下命令打开当前用户的crontab文件&#xff1a; crontab -e * * * * * /export/test.sh >> /export/test.log 2>&1/export/test.s…

什么是量化机器人?它能来作些什么?一篇文章带你了解!

在科技日新月异的今天&#xff0c;我们经常会听到一些听起来高大上的词汇&#xff0c;比如“人工智能”、“大数据”和“量化交易”。而在这其中&#xff0c;“量化机器人”更是一个让人既好奇又略感神秘的存在。今天&#xff0c;我们就用通俗易懂的语言&#xff0c;一起来揭开…

通知notification

通知 权限&#xff1a;manifest.xml&#xff0c;可以不提前写&#xff0c;后面写代码时显示缺少点击添加即可。 <uses-permission android:name"android.permission.VIBRATE"/>//振动权限 <uses-permission android:name"android.permission.POST_NOT…

洛谷 7.10 数数

Vanya and Books - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) ac代码 #include<bits/stdc.h> typedef long long ll;#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) const ll N1e3; using namespace std;int main() {IOS;ll x;cin>>x;ll ans0,px…

阿一课代表随堂分享:红队反向代理之使用frp搭建反向代理

frp反向代理 frp简介 frp 是一个开源、简洁易用、高性能的内网穿透和反向代理软件&#xff0c;支持 tcp, udp, http, https等协议。 frp 是一个可用于内网穿透的高性能的反向代理应用&#xff0c;分为服务端frps和客户端frpc&#xff0c;支持 tcp, udp, http, https 协议。详…