当前位置: 首页 > news >正文

类和对象(1)

一.类的基本概念

1.类的定义

 以上图为例①class为定义类的关键字,Date为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。
 ②为了区分成员变量,一般习惯上成员变量会加一个特殊标识,如成员变量前面或者后面加_ 或者 m开头,注意C++中这个并不是强制的,只是一些惯例,具体看公司的要求。

③ C++中struct也可以定义类,C++兼容C中struct的用法,同时struct升级成了类,明显的变化是struct中可以定义函数,一般情况下我们还是推荐用class定义类。
④定义在类内的成员函数默认为inline。

 

2.访问限定符

C++实现封装的一种方式是用类将对象的属性与方法结合在一起,让对象更完善。通过访问权限(如 public / protected / private ),有选择性地将接口提供给外部用户使用,既隐藏内部细节,又确保数据安全。

以下是三种访问限定符的区别:

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

3.类域

C++类域指类定义的范围,类成员(属性、方法等)均位于其中,特点如下:
 
①作用域范围:成员仅在类内可见,类外需通过对象/指针/引用访问(受访问权限限制)。

②成员访问规则:类内可直接访问成员;类外需通过对象名/指针/引用 + 运算符( . / -> )访问,且受public/protect/private权限控制。

③作用域解析运算符( :: ):类外定义成员函数时,需用  ::  指明所属类域。 

④嵌套类:嵌套类有独立类域,外层类与内层类成员无法直接互访(除非声明友元)。

⑤与全局域区别:全局域成员全局可见,类域成员仅在类内或通过对象访问,实现数据隐藏与封装。

 

二.类的实例化

 1.实例化

类的实例化是通过类创建具体对象的过程,对象是类的实例,实例化时调用构造函数初始化对象。
      一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量。打个比方:类实例化出对象就像现实中使用建筑设计图建造出房子,类如同设计图,规划了成员变量的类型、功能等,但本身没有实体也不能存储数据;而实例化出的对象则像按设计图修建的房子,拥有真实的物理空间,可存储具体数据。

以上代码:

1. 对象创建: main  函数中  Date d1;  和  Date d2;  分别实例化出  d1  和  d2  两个  Date  类对象,为对象分配内存空间存储私有成员变量( _year 、 _month 、 _day  )。

2. 初始化:通过  d1.Init(2025, 5, 2);  和  d2.Init(2024, 2, 14);  调用公有成员函数  Init  ,对实例化对象的成员变量进行初始化。

3. 成员访问:利用公有成员函数  Print  访问并输出对象的私有成员变量值,符合类的封装特性,外部不能直接访问私有成员。

 2.对象的大小

分析一下类对象中包含哪些成员呢?类实例化出的每个对象,都有独立的数据空间,所以对象中肯定包含成员变量。那么成员函数是否包含其中呢?

 首先,函数被编译后是一段指令,对象中无法存储这些指令,它们存储在一个单独的区域(代码段)。若对象非要存储成员函数相关内容,只能是成员函数的指针。

 进一步分析,对象中是否有存储指针的必要呢?以  Date  类为例,实例化出  d1  和  d2  两个对象, d1  和  d2  都有各自独立的成员变量  _year 、 _month 、 _day  来存储各自的数据,但  d1  和  d2  的成员函数  Init 、 Print  的指针却是一样的。如果在对象中存储成员函数指针,就会造成浪费。要是用  Date  类实例化100个对象,成员函数指针就会重复存储100次,这显然是极大的浪费。

这张图展示了两种对象存储方式设计。设计一将类成员变量(如 _name 、 _gender 、 _age  )和类成员函数(如 SetPersonInfo ,PrintPersonInfo  )统一存储。设计二则把类成员变量单独存储,不同对象的成员变量各自独立;类成员函数存于公共代码区的类成员函数表中,被所有对象共享。对比两种设计,凸显不同存储策略对对象内存管理的差异。

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

 以上代码,定义了  A 、 B 、 C  三个类。 A  类包含私有成员变量  _c ( char  类型 )和  _i ( int  类型 )以及公有成员函数  print ; B  类仅有公有成员函数  print ; C  类为空类。在  main  函数中实例化了这三个类的对象,并使用  sizeof  运算符输出对象大小。调试控制台显示了相应结果,展示了不同类对象大小在内存中的体现。

值得注意的是:

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

 

三.this指针

1.this指针的基本概念

定义

this  指针是C++ 中一个隐含的指针,它指向当前被调用成员函数所属的对象。

 作用

- 区分成员变量和局部变量:当成员函数中局部变量与成员变量同名时,可通过  this  指针明确访问成员变量。

- 返回当前对象:在成员函数中可利用  this  指针返回当前对象(常返回 *this ),支持链式调用等操作。

 特性

 - 存在于非静态成员函数中,静态成员函数没有  this  指针,因为静态成员函数不属于某个具体对象。

- 由编译器自动传递,无需程序员手动传递。

 在这段C++代码的  Date  类中, Init  成员函数里使用了  this  指针。 this  指针是一个隐含于非静态成员函数中的指针,它指向当前调用该成员函数的对象。

 具体到这里:

  ①区分变量:函数参数  year 、 month 、 day  与类的私有成员变量  _year 、 _month 、 _day  名称不同,但使用  this->  明确表示是在操作对象自身的成员变量。若参数名与成员变量名相同,比如  void Init(int _year, int _month, int _day)  ,就更能体现  this->  的必要性,用  this->_year = _year;  才能准确将参数值赋给对象的成员变量。

 ②隐含存在: this  指针由编译器自动传递,无需手动传入。当对象调用  Init  函数时,编译器会把该对象的地址传给  this  指针,在函数内部就能通过它访问和操作对象的成员。

2.this相关的两段代码

以上代码中的指针  p  虽指向  nullptr  ,但  Print  函数是普通成员函数且未访问对象的成员变量 ,没有用到  this  指针指向的对象数据,仅执行输出语句,所以不会引发空指针解引用错误,能正常运行。

 

 以上代码中的Print  函数未访问对象成员变量,仅执行输出语句,没用到  this  指针指向的对象数据,所以即便指针  p  为  nullptr  ,也不会引发空指针解引用错误,能正常运行。

 

四.对C++封装的基本认识

C++中数据和函数都放到了类里面,通过访问限定符进行了限制,不能再随意通过对象直接修改数据,这是C++封装的一种体现,这个是最重要的变化。这里的封装的本质是一种更严格规范的管理,避免出现乱访问修改的问题。当然封装不仅仅是这样的,我们后面还需要不断的去学习。
 
• C++中有一些相对方便的语法,比如Init给的缺省参数会方便很多,成员函数每次不需要传对象地址,因为this指针隐含的传递了,方便了很多,使用类型不再需要typedef用类名就很方便

相关文章:

  • Sqlserver-数据库的事务日志已满,原因为“LOG_BACKUP”。
  • C#核心概念解析:析构函数、readonly与this关键字
  • python模块管理环境变量
  • 无损图片压缩 本地处理 批量处理提升效率 无需联网+无广告
  • 位图——求两数之和
  • 力扣热题——查找包含给定字符的单词
  • 上海内推 | 上海算法创新研究院-上海交大联合招收空间智能/具身智能算法实习生
  • springboot中redis的事务的研究
  • 动态规划dp
  • 力扣刷题DAY16(二叉树+迭代遍历)
  • NHANES指标推荐:PHDI
  • 数据库blog6_商业数据库下载知识
  • Day 34
  • 【强化学习】#7 基于表格型方法的规划和学习
  • 续位值运算---左移、右移
  • 2025年安克创新Anker社招校招入职测评 | 3天备考、自适应能力cata测评北森题库、安克创造者启航试炼、安克AI能力测评能力测评历年真题
  • 抖音出品AI短剧《牧野诡事》能否给AI短剧带来新一轮爆发?
  • Linux中的nfs
  • Linux(6)——第一个小程序(进度条)
  • python打卡day35@浙大疏锦行
  • pinterest设计网站/seo 公司
  • 自己做的网站服务器开了进不去/怎么在百度制作自己的网站
  • 做医疗竞价网站/百度指数批量查询工具
  • 做的漂亮的家居网站/关键词seo公司
  • 可以做猫头像的网站/全国推广优化网站
  • 广西灵山县住房和城乡建设局网站/百度投诉电话客服24小时