C++初阶:类和对象(上)

1. 类的定义

1.1 类的定义格式

  • class 为定义类的关键字,Stack 为类的名字,{ } 中为类的主体,注意类定义结束后的分号不能省略。类体中的内容为类的成员:类中的变量称为类的属性成员变量 ;类中的函数称为类的方法成员函数
  • 为了区分成员变量,一般习惯上成员变量会加一个特殊标识,如成员变量前面或后面加 _ 或者 m 开头,注意C++中这个并不是强制的,只是一些惯例,具体看公司的要求。
  • C++中 struct 也可以定义类,C++中兼容C中 struct 的用法 ,同时 struct 升级 成了类,明显的变化是 struct 中可以定义函数,一般情况下,我们还是推荐使用 class 定义类。
  • 定义在类里面的成员函数默认为 inline

C++中 struct 不需要用 typedef ,后面的类名就可以代表类型;

1.2 访问限定符

  • C++ 中一种实现封装 的方式,用类将对象的属性方法 结合在一块,让对象更加完善,通过访问权限,选择性的将其接口提供给外部的用户使用。
  • public (公开的)修饰的成员在类外可以被直接访问;protected (受保护的) 和private(私有的)修饰的成员在类外不能被直接访问,protected 和 private 是一样的,后继章节才会体现出他们的区别。
  • 访问权限作用域从该访问限定符出现的位置开始直到出现下一个访问限定符为止,如果后面没有出现访问限定符,作用域就到**}** 即类结束为止。
  • class定义成员没有被访问限定符修饰时默认为private 修饰,struct 默认为public
  • 一般成员变量 都会被限制为private / protected ,需要给别人使用的函数默认为 public

1.3 类域

  • 类定义了一个新的作用域 ,类的所有成员 都在类的作用域中,在类体外定义成员时,需要使用 **::**作用域操作符指明成员属于哪个类域。
  • 类域影响的是编译的查找规则 ,下面程序中 Init 如果不指定类域Stack,那么编译器就会把 Init当成全局函数 ,那么编译时,找不到 array 等成员的声明或者定义在哪里,就会报错。指定类域 Stack就是知道 Init 是成员函数,当前域找不到 array 等成员就会去类域中查找。

2. 实例化

2.1 实例化概念

  • 类型在物理内存 中创建对象的过程,称为实例化出对象。
  • 类的对象是一种抽象描述,是一个模型一样的东西,限定了类有哪些成员变量,这些成员变量只是声明,并没有创造出空间,用类实例化出对象时,才会分配空间。
  • 一个类能实例化出多个 对象,实例化出的对象,占用实际的物理空间 ,储存类成员变量 。打个比方:类实例化出的对象就像现实中使用建筑设计图建造出房子,类就像设计图纸,设计图规划了有多少个房间,房间大小功能等,但是并没有实体的建筑存在,也不能住人,用设计图修建出的房子,房子才能住人。同样,类就像设计图一样,不能存储数据,实例化出的对象分配物理内存存储数据

以下是代码示例:

2.2 对象大小

类实例化出的每个对象,都有独立 的数据空间,对象中肯定要包含成员变量,但是并不包含 成员函数。函数被编译后是一串指令,对象中无法储存,这些指令存储在单独的区域(代码段) ,如果对象中非要储存的话,只能是成员函数的指针 ,但是并没有 储存的必要。因为,Date 实例化出的对象 date1 和 date2 ,date1 和 date2 都有各自独立的成员变量,但是成员函数指针却是相同 的,储存在对象中就浪费了,几个还好,如果实例化出一千个,一万个呢?就会造成指针重复储存 。额外说一下,这里的成员函数指针并不需要 存储,函数指针是一个地址,调用函数被编译成汇编指令,【call地址】,在编译器链接的时候,就要找到函数的地址,不是在运行的时候找,只有动态多态是在运行时找,需要存储函数地址(以后讲)。

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

需要注意的是:如果一个类中并没有成员变量,那么这个类创建的对象大小是1个字节,为什么没有成员变量还要给一个字节呢?因为如果一个字节都不给,怎么表示对象存在过呢?要知道实例化的对象要占据独立的内存空间的。所以给一个字节,纯粹是为了占位标识对象的存在。

3. this 指针

  • Date 类中有 Init 与 Print 两个成员函数,函数体中没有 关于不同对象的区分,那当 d1 调用 Init 和Print 函数时,该函数是如何知道该访问的是的 d1 对象还是 d2 对象呢? C++ 这里给了一个隐含的this 指针解决了这个问题。
  • 编译器编译后,类的成员函数默认都会在形参第一个 位置,增加一个当前类型 的指针,叫做 this指针。比如 Date 类的 Inti 的真实原型为,void Init (Date* const this, int year, int month, int day)
  • 类的成员函数 中访问成员变量 ,本质都是通过 this指针访问的,如 Init 函数中给 _year 赋值,this->_year = year;
  • C++ 规定不能实参和形参 的位置显示的写 this 指针(编译时编译器会处理),但是可以在函数体内显示使用 this 指针。

制作不易,谢谢大家的点赞关注支持!!!

相关推荐
St_Ludwig几秒前
C语言小撰特殊篇-assert断言函数
c语言·c++·后端·算法
PaLu-LI9 分钟前
ORB-SLAM2源码学习:Initializer.cc:Initializer::Normalize地图初始化——坐标归一化
c++·opencv·学习·算法·ubuntu·计算机视觉
秋说12 分钟前
【数据结构 | C++】部落
数据结构·c++·算法
techdashen33 分钟前
Go与黑客(第四部分)
开发语言·后端·golang
宇宙大豹发39 分钟前
【Python】爬虫实战:高效爬取电影网站信息指南(涵盖了诸多学习内容)
开发语言·爬虫·python·学习·python爬虫·python代码·python使用
蓝桉柒71 小时前
web前端开发--动画效果
开发语言·前端·css
芥末虾1 小时前
【优选算法】KMP模式匹配算法 {算法介绍;算法原理:核心原理,如何求next数组;代码实现}
c语言·c++·算法·kmp·字符串模式匹配
薔薇十字1 小时前
【代码随想录day36】【C++复健】1049. 最后一块石头的重量 II ; 494. 目标和 ;474.一和零
c++·算法·leetcode
hummhumm1 小时前
第 32 章 - Go语言 部署与运维
java·运维·开发语言·后端·python·sql·golang
techdashen1 小时前
Go与黑客(第二部分)
开发语言·后端·golang