C++:类与对象(上)

目录

一、类的定义

1.1类的定义格式

1.2访问限定符

 1.3类域

二、实例化

2.1实体化的概念

2.2类对象的大小 

三、this指针 


前言:

这篇文章是对类和对象的初步介绍,我将用三篇文章描述类和对象,希望对大家有所帮助

一、类的定义

什么是对象:

对象是一个实体,我们眼睛能看到的实体都是对象。

什么是类:

类是用来对实体(对象)进行描述的,如对象有什么属性,功能等。类可以看做C语言中的结构体的加强版,在C++中结构体被认为是类的一种。

1.1类的定义格式

class是类的关键字,stack是类的名字,{}中是类的成员,注意类定义结束时后⾯分号不能省略,类中的成员包括变量和函数。类中的变量称为类的属性或成员变量,类中的函数称为类的⽅法或 者成员函数。

#include<iostream>
using namespace std;
class stack//类型名
{//类的成员// //函数称为类的⽅法或 者成员函数void add()此时为内联函数{//.......}//类的属性或成员变量int a = 10;int b = 0;
};//后⾯分号不能省略
//第二种,可以把声明留在类里,定义放在外面或别的文件
///比如类的声明在.h文件,定义在.c文件
//.h文件
class stack//类型名
{//类的成员// //函数称为类的⽅法或 者成员函数
public:void add();//类的属性或成员变量int a = 10;int b = 0;
};//后⾯分号不能省略
//.c文件
void stack::add()
{//........
}

类的定义中需要注意的细节:

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

②在类中定义的成员函数,默认为是内联函数(inline)

③为了避免函数形参和类中的成员函数名相同,为了避免混淆最好加上一些特殊标记。

④两种定义方法都可以使用,必进编译器会忽略长函数,我们可以将短的函数写在里面,长的函数写在外面

1.2访问限定符

访问限定符是C++的一种封装方式,将类的属性和类的方法联系在一起,通过访问限制选择性的将一些内容给外界使用。

public修饰的成员在类外可以直接被访问
private修饰的成员在类外不能直接被访问
protected修饰的成员在类外不能直接被访问

访问限定符中的细节:

①一个访问限定符的作用域,从这个访问限定符开始到下一个访问限定符结束,如果没有就到}结束。

②class当类内没有访问限定符时,默认为private;struct中默认为public。

③public修饰的成员在类外可以直接被访问;protected和private修饰的成员在类外不能直接被访问,protected和private是⼀样的,这里我们还未详细讲解,以后继承章节才能体现出他们的区别。

④public在类外和类内都可以被直接访问。

class stack
{
public:int a = 10;int b = 3;
private:void add(){//.....}
protected:int c = a + b;//public在类内可以直接访问add();//private不可以直接访问
};

 1.3类域

上一篇文章我们讲了C++中的域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找⼀个变量/函数/ 类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。局部域和全局域除了会影响 编译查找逻辑,还会影响变量的⽣命周期,命名空间域和类域不影响变量⽣命周期。 

类域是一个全新的作用域,在类外要定义时,需要使⽤ :: 作⽤域操作符指明成员属于哪个类域。

class stack
{
public:void STinit(int n=4);
private:int val;int top = 0;int capacity = 4;
};
void stack::STinit(int n = 4)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail!");}
}
int main()
{stack st;st.STinit();
}

二、实例化

2.1实体化的概念

如果说类是对对象的描述,而对象可以是眼睛看到的任何实体,那我们也可以认为对象是一个房子时,类是对房子的描述,即为图纸。在没有实体化的时候,是不占空间的。

类是可以定义多个对象的,就像一个图纸可以建很多个房子。 

class stack
{
public:void STinit(int n=4);
private:int val;int top = 0;int capacity = 4;
};
void stack::STinit(int n = 4)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail!");}
}
int main()
{stack st1;stack st2;st1.STinit();st2.STinit();
}

2.2类对象的大小 

之前我们在上面讲述了Class是C语言中struct的加强版,那么类对象的大小,是否和结构体的大小有关呢?

答案是相关的,但是也有一些不同。

①类中包含成员变量和成员函数,类实例化出的每个对象,都有独⽴的数据空间,所以对象中肯定包含 成员变量,那么成员函数是否包含呢?

→→⾸先函数被编译后是⼀段指令,对象中没办法存储,这些指令存储在⼀个单独的区域(代码段),那么对象中⾮要存储的话,只能是成员函数的指针

→→对象中是否有存储指针的必要呢,Date实例化d1和d2两个对象,d1和d2都有各⾃独⽴的成员变量 _year/_month/_day存储各⾃的数据,但是d1和d2的成员函数Init/Print指针却是⼀样的,存储在对象 中就浪费了。如果⽤Date实例化100个对象,那么成员函数指针就重复存储100次,太浪费了。

→→所以成员函数不在类中存储,他们在公共的代码区中存储。

这样类中就只用存储成员变量这与结构体就相同了,遵循内存对齐规则。

如果这个类是空(没有成员变量)的,没有成员,那就是1个字节,不存数据,就标识有这个对象存在过。 

三、this指针 

Date类中有print和init成员函数,由上可知他们存储在相同位置,当我们创建不同Data的不同对象时,如何分辨是谁的函数呢?那么这⾥就要看到C++给了 ⼀个隐含的this指针解决这⾥的问题。

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

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

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

#include<iostream>
using namespace std;
class Date
{
public:// void Init(Date* const this, int year, int month, int day)void Init(int year, int month, int day){// 编译报错:error C2106: “=”: 左操作数必须为左值// this = nullptr;// this->_year = year;this->_year = year;this->_month = month;this->_day = day;}void Print(){cout << _year << "/" << _month << "/" << _day << endl;}
private:// 这⾥只是声明,没有开空间int _year;int _month;int _day;
};
int main()
{// Date类实例化出对象d1和d2Date d1;Date d2;// d1.Init(&d1, 2024, 3, 31);d1.Init(2024, 3, 31);d1.Print();d2.Init(2024, 7, 5);d2.Print();return 0;
}

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

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

相关文章

jenkins打包java项目报错Error: Unable to access jarfile tlm-admin.jar

jenkins打包boot项目 自动重启脚本失败 查看了一下项目日志报错&#xff1a; Error: Unable to access jarfile tlm-admin.jar我检查了一下这个配置&#xff0c;感觉没有问题&#xff0c;包可以正常打&#xff0c; cd 到项目目录下面&#xff0c;手动执行这个sh脚本也是能正常…

这可能是最详细的 Dagger2 使用教程 二(限定注解 @Named、@Qulifier 和 范围注解 @Singleton、@Scope)

通过上一篇文章我们知道了 Dagger2 的基本使用&#xff0c;在这篇文章中&#xff0c;我们将讲解 Dagger 中的两个重要概念以及相关注解。 这可能是最详细的 Dagger2 使用教程 一&#xff08;基本使用&#xff09; 类型上再加限定&#xff1a;Named 和 Qulifier 注解的使用 通…

罗技K380无线键盘及鼠标:智慧互联,一触即通

目录 1. 背景2. K380无线键盘连接电脑2.1 键盘准备工作2.2 电脑配置键盘的连接 3. 无线鼠标的连接3.1 鼠标准备工作3.2 电脑配置鼠标的连接 1. 背景 有一阵子经常使用 ipad&#xff0c;但是对于我这个习惯于键盘打字的人来说&#xff0c;慢慢在 ipad 上打字&#xff0c;实在是…

北摩高科应邀参加空客供应商大会

民航市场一直以来都是北摩高科重要的战略发展方向&#xff0c;进入国际航空巨头供应链体系也是公司的长期愿景。7月9日至10日&#xff0c;北摩高科公司应邀参与空客集团在天津举办的供应商大会及晚宴。 图1&#xff1a;空客集团采购总监Juergen Westermeier与北摩高科领导 会上…

基于Java+SpringMvc+Vue技术的药品进销存仓库管理系统设计与实现系统(源码+LW+部署讲解)

注&#xff1a;每个学校每个老师对论文的格式要求不一样&#xff0c;故本论文只供参考&#xff0c;本论文页数达到60页以上&#xff0c;字数在6000及以上。 基于JavaSpringMvcVue技术的在线学习交流平台设计与实现 目录 第一章 绪论 1.1 研究背景 1.2 研究现状 1.3 研究内容…

Linux权限相关

目录 Linux中的用户 Linux权限管理 Linux的文件访问者分类 Linux的文件类型和访问权限 文件类型 文件权限 文件权限的修改 文件所有者修改 文件所有者所在组修改 目录权限 粘滞位 文件掩码 在Linux中&#xff0c;权限包括用户的权限和文件的权限 Linux中的用户 在…

jenkins系列-06.harbor

https://github.com/goharbor/harbor/releases?page2 https://github.com/goharbor/harbor/releases/download/v2.3.4/harbor-offline-installer-v2.3.4.tgz harbor官网&#xff1a;https://goharbor.io/ 点击 Download now 链接&#xff0c;会自动跳转到上述github页面&am…

t-SNE降维可视化并生成excel文件使用其他画图软件美化

t-sne t-SNE&#xff08;t-分布随机邻域嵌入&#xff0c;t-distributed Stochastic Neighbor Embedding&#xff09;是由 Laurens van der Maaten 和 Geoffrey Hinton 于 2008 年提出的一种非线性降维技术。它特别适合用于高维数据的可视化。t-SNE 的主要目标是将高维数据映射…

Milvus核心设计(2)-----TSO机制详解

目录 背景 动机 Timestamp种类及使用场景 Guarantee timestamp Service timestamp Graceful time Timestamp同步机制 主流程 时间戳同步流程 背景 Milvus 在设计上突出了分布式的设计,虽然Chroma 也支持分布式的store 与 query。但是相对Milvus来说,不算非常突出。…

LabVIEW心电信号自动测试系统

开发了一种基于LabVIEW的心电信号自动测试系统&#xff0c;通过LabVIEW开发的上位机软件&#xff0c;实现对心电信号的实时采集、分析和自动化测试。系统包括心电信号采集模块、信号处理模块和自动化测试模块&#xff0c;能够高效、准确地完成心电信号的测量与分析。 硬件系统…

Vue3 markRaw的使用

markRaw 作用:将一个对象标记为不可以被转化为代理对象。返回该对象本身。 应用场景: 1.有些值不应被设置成响应式时,例如复杂的第三方类库等 2.当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能 3.在动态渲染组件的时候我们就可以使用 markRaw 包裹。markRaw 的…

秋招突击——7/9——MySQL索引的使用

文章目录 引言正文B站网课索引基础创建索引如何在一个表中查看索引为字符串建立索引全文索引复合索引复合索引中的排序问题索引失效的情况使用索引进行排序覆盖索引维护索引 数据库基础——文档资料学习整理创建索引删除索引创建唯一索引索引提示复合索引聚集索引索引基数字符串…

git 笔记

文章目录 前言一些代码托管仓库初步的一些理解设置个人信息创建自己的仓库查看仓库的状态添加文件到暂存区把暂存区的文件添加到版本库查询两个文件之间的区别查看版本迭代信息版本回滚查看所有的历史版本快捷切换应用感受分支的一些相关的操作假设新建一个分支并跳转到这个分支…

【ARM】MDK安装ARM_compiler5无法打开安装程序

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 在客户安装了最新版本的MDK5.37及后续更新版本&#xff0c;但原工程使用ARM_Compiler_5.06进行编译和调试&#xff0c;需安装ARM_Compiler_5.06的编译器版本&#xff0c;但在解压缩的过程中后续无法打开ARM_Compiler…

FinalShell介绍,安装与应用

目录 一、什么是finalshell 二、finalshell功能 三、为什么要用finalshell 四、安装finalshell 五、finalshell使用 1.添加连接 获取虚拟ip地址 2.启动连接 一、什么是finalshell FinalShell是一体化的的服务器,网络管理软件,不仅是ssh客户端,还是功能强大的开发,运维工…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(四)-无人机系统(UAS)命令与控制(C2)通信用例

引言 本文是3GPP TR 22.829 V17.1.0技术报告&#xff0c;专注于无人机&#xff08;UAV&#xff09;在3GPP系统中的增强支持。文章提出了多个无人机应用场景&#xff0c;分析了相应的能力要求&#xff0c;并建议了新的服务级别要求和关键性能指标&#xff08;KPIs&#xff09;。…

Re:从零开始的C++世界——(一)入门基础

文章目录 C发展历史1.命名空间1.1 namespace的价值1.2 namespace的定义1.3 命名空间使⽤ 2.C输⼊&输出3.缺省参数3.1 缺省参数的概念3.2 缺省参数的分类 4.函数重载5.引⽤5.1引⽤的概念和定义5.2 引⽤的特性5.3 const引⽤5.4 使用场景5.5 指针和引⽤的关系 6.内联函数6.1内…

NAT地址转换+多出口智能选路,附加实验内容

本章主要讲&#xff1a;基于目标IP、双向地址的转换 注意&#xff1a;基于目标NAT进行转换 ---基于目标IP进行地址转换一般是应用在服务器端口映射&#xff1b; NAT的基础知识 1、服务器映射 服务器映射是基于目标端口进行转换&#xff0c;同时端口号也可以进行修改&…

Mybatis-plus 集成 PostgreSQL 数据库自增序列问题记录

1.创建序列并绑定id CREATE SEQUENCE biz_factory_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;"id" int4 NOT NULL DEFAULT nextval(sys_user_seq::regclass), 2.实体设置KeySequence和TableId注解 注意IdType.INPUT 和 KeySequence(value …

Java巅峰之路---基础篇---综合练习(面向对象)

目录 文字版格斗游戏 基础版 souf输出语句 进阶版 键盘录入的说明 复杂对象数组练习 需求&#xff1a; 添加和遍历 删除和遍历 修改和遍历 文字版格斗游戏 基础版 格斗游戏&#xff0c;每个游戏角色的姓名&#xff0c;血量&#xff0c;都不相同&#xff0c;在选定人…