c++初阶知识——类和对象(1)

news2024/9/19 11:12:11

目录

1.类和对象

1.1 类的定义

1.2 访问限定符

1.3 类域

 2.实例化

2.1 实例化概念

2.2 对象大小 

内存对齐规则 

3.this指针


1.类和对象

1.1 类的定义

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

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Stack
{
public:
	// 成员函数
	void Init(int n = 4)
	{
		array = (int*)malloc(sizeof(int) * n);
		if (nullptr == array)
		{
			perror("malloc申请空间失败");
			return;
		}
		capacity = n;
		top = 0;
	}
	void Push(int x)
	{
		// ...扩容
		arr[top++] = x;
	}
	int Top()
	{
		assert(top > 0);
		return array[top - 1];
	}
	void Destroy()
	{
		free(array);
		array = nullptr;
		top = capacity = 0;
	}

private:
	int* arr;
	int size;
	int capacity;
};
int main()
{
	
		Stack st;
		st.Init();
		st.Push(1);
		st.Push(2);
		cout << st.Top() << endl;
		st.Destroy();
		return 0;
	
}

(2)为了区分成员变量,⼀般习惯上成员变量会加⼀个特殊标识,如成员变量前⾯或者后⾯加_ 或者 m开头,注意C++中这个并不是强制的,只是⼀些惯例,具体看公司的要求。

class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
private:
// 为了区分成员变量,⼀般习惯上成员变量
// 会加⼀个特殊标识,如_ 或者 m开头
int _year; // year_ m_year
int _month;
int _day;
};
int main()
{
Date d;
d.Init(2024, 3, 31);
return 0;
}

(3)C++中struct也可以定义类,C++兼容C中struct的⽤法,同时struct升级成了类,明显的变化是struct中可以定义函数,区别是使用struct定义的类的成员默认为public,而class定义的类的成员默认为private(public和private定义后面会讲到),⼀般情况下我们还是推荐⽤class定义类。

#include<iostream>
using namespace std;
// C++升级struct升级成了类
// 1、类⾥⾯可以定义函数
// 2、struct名称就可以代表类型
// C++兼容C中struct的⽤法
typedef struct ListNodeC
{
struct ListNodeC* next;
int val;
}LTNode;
// 不再需要typedef,ListNodeCPP就可以代表类型
struct ListNodeCPP
{
void Init(int x)
{
next = nullptr;
val = x;
}
ListNodeCPP* next;
int val;
};
int main()
{
return 0;
}

 (4)定义在类⾯的成员函数默认为inline。

1.2 访问限定符

 (1)C++⼀种实现封装的⽅式,⽤类将对象的属性与⽅法结合在⼀块,让对象更加完善,通过访问权限选择性的将其接⼝提供给外部的⽤⼾使⽤

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

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

(4)class定义成员没有被访问限定符修饰时默认为privatestruct默认为public

(5)⼀般成员变量都会被限制为private/protected,需要给别⼈使⽤的成员函数会放为public。

【面试题】

问题:C++中struct和class的区别是什么?

解答:C++需要兼容C语言,所以C++中struct可以当成结构体使用。另外C++中struct还可以用来
定义类。和class定义类是一样的,区别是struct定义的类默认访问权限是public,class定义的类
默认访问权限是private。注意:在继承和模板参数列表位置,struct和class也有区别,后序给大
家介绍。

1.3 类域

(1)类定义了⼀个新的作⽤域,类的所有成员都在类的作⽤域中,在类体外定义成员时,需要使⽤ :: 作⽤域操作符指明成员属于哪个类域。

(2)类域影响的是编译的查找规则,下⾯程序中Init如果不指定类域Stack,那么编译器就把Init当成全局函数,那么编译时,找不到array等成员的声明/定义在哪⾥,就会报错。指定类域Stack,就是知道Init是成员函数,当前域找不到的array等成员,就会到类域中去查找。

#include<iostream>
using namespace std;
class Stack
{
public:
// 成员函数
void Init(int n = 4);

private:
// 成员变量
int* array;
size_t capacity;
size_t top;
};
// 声明和定义分离,需要指定类域
void Stack::Init(int n)
{
array = (int*)malloc(sizeof(int) * n);
if (nullptr == array)
{
perror("malloc申请空间失败");
return;
}
capacity = n;
top = 0;
}
int main()
{
Stack st;
st.Init();
return 0;
}

 2.实例化

2.1 实例化概念

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

(2)类是对象进⾏⼀种抽象描述,是⼀个模型⼀样的东西,限定了类有哪些成员变量,这些成员变量只是声明,没有分配空间,⽤类实例化出对象时,才会分配空间。

(3)⼀个类可以实例化出多个对象,实例化出的对象 占⽤实际的物理空间,存储类成员变量。打个⽐⽅:类实例化出对象就像现实中使⽤建筑设计图建造出房⼦,类就像是设计图,设计图规划了有多少个房间,房间⼤⼩功能等,但是并没有实体的建筑存在,也不能住⼈,⽤设计图修建出房⼦,房⼦才能住⼈。同样类就像设计图⼀样,不能存储数据,实例化出的对象分配物理内存存储数据。

代码实例:

#define _CRT_SECURE_NO_WARNINGS 1
#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()
{
	// Date类实例化出对象d1和d2
	Data d1;
	Data d2;
	d1.Init(2024, 9,9);
	d1.print();

	d2.Init(1919, 5, 4);
	d2.print();
	return 0;
}

2.2 对象大小 

   分析⼀下类对象中哪些成员呢?类实例化出的每个对象,都有独⽴的数据空间,所以对象中肯定包含成员变量,那么成员函数是否包含呢?⾸先函数被编译后是⼀段指令,对象中没办法存储,这些指令存储在⼀个单独的区域(代码段),那么对象中⾮要存储的话,只能是成员函数的指针。

再分析⼀下,对象中是否有存储指针的必要呢,Date实例化d1和d2两个对象,d1和d2都有各⾃独⽴的成员变量_year/_month/_day存储各⾃的数据,但是d1和d2的成员函数Init/Print指针却是⼀样的,存储在对象中就浪费了。

如果⽤Date实例化100个对象,那么成员函数指针就重复存储100次,太浪费了。这⾥需要再额外啰嗦⼀下,其实函数指针是不需要存储的,函数指针是⼀个地址,调⽤函数被编译成汇编指令[call 地址], 其实编译器在编译链接时,就要找到函数的地址,不是在运⾏时找,只有动态多态是在运⾏时找,就需要存储函数地址,这个我们以后会讲解

 

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

内存对齐规则 

 (1)第⼀个成员在与结构体偏移量为0的地址处。

(2)其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。

(3)注意:对⻬数 = 编译器默认的⼀个对⻬数 与 该成员⼤⼩的较⼩值。

(4)VS中默认的对⻬数为8

(5)构体总⼤⼩为:最⼤对⻬数(所有变量类型最⼤者与默认对⻬参数取最⼩)的整数倍。

(6)如果嵌套了结构体的情况,嵌套的结构体对⻬到⾃⼰的最⼤对⻬数的整数倍处,结构体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体的对⻬数)的整数倍。

3.this指针

(1)Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调⽤Init和Print函数时,该函数是如何知道应该访问的是d1对象还是d2对象呢?那么这⾥就要看到C++给了⼀个隐含的this指针解决这⾥的问题

(2)编译器编译后,类的成员函数默认都会在形参第⼀个位置,增加⼀个当前类类型的指针,叫做this指针。⽐如Date类的Init的真实原型为: void Init(Date* const this, int year,int month, int day)

(3)类的成员函数中访问成员变量,本质都是通过this指针访问的,如Init函数中给_year赋值: this->_year = year;

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

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

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

相关文章

数据(图像)增广

一、数据增强 1、增加一个已有数据集&#xff0c;使得有更多的多样性&#xff0c;比如加入不同的背景噪音、改变图片的颜色和形状。 2、增强数据是在线生成的 3、增强类型&#xff1a; &#xff08;1&#xff09;翻转 &#xff08;2&#xff09;切割 &#xff08;3&#xf…

AI大模型API:开启智能应用的新纪元

AI大模型API是当今技术领域的重要突破&#xff0c;它们以其卓越的性能和强大的计算能力引领着人工智能的发展。这些API不仅仅是一种技术工具&#xff0c;更是推动智能化时代的核心驱动力。通过AI大模型类API&#xff0c;我们可以利用先进的算法和深度学习模型&#xff0c;实现各…

k8s NetworkPolicy

Namespace 隔离 默认情况下&#xff0c;所有 Pod 之间是全通的。每个 Namespace 可以配置独立的网络策略&#xff0c;来 隔离 Pod 之间的流量。 v1.7 版本通过创建匹配所有 Pod 的 Network Policy 来作为默认的网络策略 默认拒绝所有 Pod 之间 Ingress 通信 apiVersion: …

heic格式转化jpg?三种方法轻松解决Heic图片转换

HEIC是苹果IOS 11系统推出的图片格式&#xff0c;它采用了最新的图片处理技术&#xff0c;在不损坏图片质量的情况下&#xff0c;减少占用系统。很多使用mac系统的小伙伴都有这样的困惑&#xff0c;如何将HEIC格式的图片转换成JPG呢&#xff1f;小编今天给大家分享3种适用的hei…

Oracle安装完之后设置开机自启动配置步骤

默认&#xff1a;dbca建库时都会自动创建/etc/oratab文件 [oraclelocalhost bin]# vi /etc/oratab 将“orcl:/home/oracle/product/11.2.0/dbhome_1:N”&#xff0c;改为 “orcl:/home/oracle/product/11.2.0/dbhome_1:Y”。 修改完成后&#xff0c;保存退出--选项代表开机是…

不仅是输出信息,console.log 也能玩出花

console.log 是 JavaScript 中一个常用的函数&#xff0c;用于向控制台输出信息。 console.log 虽然主要用于调试目的&#xff0c;但也包含了一些有趣的用法&#xff0c; console.log 不仅能输出文本&#xff0c;还能以更丰富的方式展示信息。 比如我们打开 B 站&#xff0c;然…

Win10安装MongoDB(详细版)

文章目录 1、安装MongoDB Server1.1. 下载1.2. 安装 2、手动安装MongoDB Compass(GUI可视工具)2.1. 下载2.2.安装 3、测试连接3.1.MongoDB Compass 连接3.2.使用Navicat连接 1、安装MongoDB Server 1.1. 下载 官网下载地址 https://www.mongodb.com/try/download/community …

ElasticSearch(二)【基本操作以及集成 SpringBoot】

启动 elasticsearch&#xff08;脚本&#xff09;、kibana&#xff08;bat脚本&#xff09; 和 elasticsearch-head-master&#xff08;npm run start&#xff09; 1、RESTful 风格 1.1、索引类基本操作 1.1.1、创建索引 PUT /索引名/类型名/文档id {请求体} 在 elasticsear…

Rewrk一个更现代的http框架基准测试实用程序

Rewrk一个更现代的http框架基准测试实用程序。HTTP基准测试&#xff08;HTTP benchmarking&#xff09;是一种测量和评估HTTP服务器或应用程序性能指标的活动。其目的是在特定条件下模拟大量用户请求&#xff0c;以测量服务器或应用程序的响应能力、吞吐量、延迟等指标&#xf…

员工微信号怎么管理

员工走私单或者离职了删除客户&#xff0c;删除撤回的消息也能看得见

强引用?软引用?弱引用?虚引用?一文带你彻底搞懂!!

强引用&#xff1f;软引用&#xff1f;弱引用&#xff1f;虚引用&#xff1f;一文带你彻底搞懂&#xff01;&#xff01; 前言引用级别强引用软引用弱引用虚引用 总结 前言 我们知道 JVM 的 GC 是不受程序控制的&#xff0c;只要满足条件就会自动触发 那他是根据什么触发的呢…

Apache防盗链、网页压缩、网页缓存

目录 网页压缩 类型 示例 动态添加模块操作步骤 重装Apache操作步骤 网页缓存 示例 操作步骤 隐藏版本信息 操作步骤 Apache防盗链 定义 原理 配置防盗链实验环境 实验环境 本地图片盗链示例 操作步骤 防盗链示例 操作步骤 网页压缩 网站的访问速度是由多个…

C语言 结构体和共用体——对结构体的操作

目录 如何访问结构体的成员&#xff1f; 结构体变量的赋值操作 结构体变量的取地址值操作 如何访问结构体的成员&#xff1f; 结构体变量的赋值操作 结构体变量的取地址值操作

C++基础技能:如何在VisualStudio中使用clang-format格式化代码

目录 1.下载 clang-format.exe程序 2.clang-format详细参数说明 3.Visual Studio中设置使用clang-format 4.创建.clang-format文件 5.在Visual Studio中触发格式化 1.下载 clang-format.exe程序 下载源&#xff1a; https://llvm.org/builds/下载最新的clang-format。ht…

开发编码规范笔记

前言 &#xff08;1&#xff09;该博客仅用于个人笔记 格式转换 &#xff08;1&#xff09;查看是 LF 行尾还是CRLF 行尾。 # 单个文件&#xff0c;\n 表示 LF 行尾。\r\n 表示 CRLF 行尾。 hexdump -c <yourfile> # 单个文件&#xff0c;$ 表示 LF 行尾。^M$ 表示 CRLF …

晨持绪电商:开一家抖音网店到底有前景吗

在数字化浪潮汹涌的今天&#xff0c;抖音作为一颗耀眼的新星&#xff0c;不仅重塑了人们的娱乐方式&#xff0c;更是成为电商领域的新战场。但许多人仍在观望&#xff0c;心中充满疑问&#xff1a;开一家抖音网店&#xff0c;究竟有没有前景? 抖音的流量优势不容忽视。凭借数亿…

CVE-2024-23692: Rejetto HTTP File Server 2.3m Unauthenticated RCE漏洞复现

目录 本文章仅供学习使用&#xff01;&#xff01;&#xff01; Rejetto HTTP介绍 漏洞简介 漏洞环境 漏洞复现 exp 复现 结果 如何修复 本文章仅供学习使用&#xff01;&#xff01;&#xff01; Rejetto HTTP介绍 Rejetto是一个流行的开源软件项目&#xff0c;主要…

【RHCE】dns实验0709

题目&#xff1a; 配置主服务器的web内容 web部分 创建web页面 修改增加etc/hosts内容且重启 测试&#xff1b; dns 区域文件 防火墙放行&#xff1a; 主服务器测试从服务器 从服务器 web dns 防火墙放行服务 selinux放行&#xff1a; 创建文件 定义特定文件 测试&#xff1…

ROS基础学习-ROS运行管理

ROS运行管理 目录 1. ROS运行管理简述2. ROS元功能包2.1 概念2.2 作用2.3 实现 3. ROS-launch文件3.1. ROS节点管理launch文件3.1.1 概念3.1.2 作用3.1.3 使用 3.2 launch文件标签 1. ROS运行管理简述 ROS是多进程(节点)的分布式框架&#xff0c;一个完整的ROS系统实现&#x…

城市窨井盖监测设备:让城市井盖不再“蹦迪”

近日&#xff0c;郑州暴雨来袭&#xff0c;街道瞬间变成河流&#xff0c;而原本默默无闻的井盖却成了“网红”&#xff0c;由于暴雨强大的水流压力&#xff0c;使它们在水中“随波逐流”上下跳动&#xff0c;网友直呼&#xff1a;这年头井盖都会“蹦迪”了。虽然是一句调侃&…