【C++初阶】第2课—类和对象(上)
2025/2/25 23:37:44
来源:https://blog.csdn.net/weixin_70620792/article/details/143818267
浏览:
次
关键词:【C++初阶】第2课—类和对象(上)
文章目录
- 1. 类
-
- 2. 实例化
-
- 3. this指针
- 4. C++和C语言实现Stack对比
1. 类
1.1 类的定义
- C++中类的关键字有两个:
class和struct
,可能大家对class比较陌生,不过struct在学习C语言和数据结构阶段应该用的比较多,没错,在C++中struct被升级为了类 - class和struct定义的类中都可以包含变量和函数,不过一般都是用class定义类
- class和struct定义的类肯定有区别,我们后面讲

- 其中class和struct后面+类的名字,{}为类的主体,类体中的内容为类的成员,另外类结束也有
;
- 为了区分成员变量,一般习惯上在成员变量前加一个标识符_或者m_,具体情况具体分析,C++不强制
- 类里面的成员函数默认为inline,内联函数



1.2 访问限定符
- C++实现了一种封装类的方式,将类和对象的属性和方法结合在一起,使得对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用
- 在C语言中,你需要手动管理代码的可见性,并通过头文件和库文件来提供接口,而在C++的类中,推出了封装的概念,借此可以通过使用权限来对自己写的函数进行选择性的封装,用户也只能访问你提供的公共权限的接口

- private和protect的区别在之后的章节讲
- 访问权限的作用域从访问限定符出现的位置到下个访问限定符出现时为止,若后面没有下个访问限定符,则作用域到 } 即类结束
- class和struct定义类的区别:class定义类时没有访问限定符时,默认为private,即不可被类外访问,而struct则是默认为public,可以被类外访问
- 一般成员变量都会被限制为private/protected,而需要给别人用的成员函数则被设置成public
- 简单理解就是,public时公共访问权限,而private和protected时私人权限,外人(类外)无权访问和修改


1.3 类域
- C++中一共有四个域,全局域、局部域、命名空间域、类域,而这个类域就是类的作用域,类的所有成员都在类域里,在类体外定义成员时,需要使用
::
作用域操作符指明成员属于哪个类域

2. 实例化
2.1 实例化概念
- 用类类型在物理内存中创建对象的过程,称为类实例化出对象
- 类是对象进行一种抽象描述,是一个模型一样的东西,限定了类有哪些成员变量,这些成员变量只是声明,没有分配空间,用类实例化出对象时,才会分配空间
- 一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量

2.2 对象大小
- 首先计算类实例化出的对象计算大小时,是不包含类里面的函数大小的,它只计算类的成员变量大小
- 首先函数被编译后是一段指令,对象中没办法存储,这些指令存储在⼀个单独的区域(代码段),那么对象中非要存储的话,只能是成员函数的指针。再分析⼀下,对象中是否有存储指针的必要呢,Date实例化d1和d2两个对象,d1和d2都有各自独立的成员变量_year/_month/_day存储各自的数据,但是d1和d2的成员函数Init/Print指针却是⼀样的,存储在对象中就浪费了。如果用Date实例化100个对象,那么成员函数指针就重复存储100次,太浪费了
- 其实函数指针是不需要存储的,函数指针是一个地址,调用函数被编译成汇编指令[call 地址], 其实编译器在编译链接时,就要找到函数的地址,不是在运行时找,只有动态多态是在运行时找,就需要存储函数地址,这个我们以后会讲解
- 上面我们分析了对象中只存储成员变量,C++规定类实例化的对象也要符合内存对齐的规则
- 第一个成员在与结构体偏移量为0的地址处
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处
- 注意:对齐数=编译器默认的⼀个对⻬数与该成员大小的较小值
- VS中默认的对齐数为8
- 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍
- 如果嵌套了结构体的情况,嵌套的结构体对齐到⾃⼰的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍

3. this指针

- 编译器在编译后,类的成员函数默认都会在形参的第一个位置,增加一个当前类型的指针,叫做this指针

- 类的成员函数中访问成员变量,本质(编译器)都是通过this指针访问的,当然我们也可以显式的添加this指针进行访问
- C++规定不能在实参和形参的位置显式使用this指针(编译器编译时会自动处理),但是在函数体内可以显式使用

- 在C++中,成员函数的地址并不直接存储在类的实例(对象)中。相反,成员函数的代码通常存储在程序的代码段(也称为文本段)中,这是一个只读区域,用于存储程序的执行代码。这部分内存是静态分配的,在程序编译时就已经确定,并在程序整个运行期间保持不变

- 补充一点的是:指针p的作用:第一个是告诉编译器可以通过它调用成员函数,第二个是调用成员函数需要传this指针(隐式),这里就是将p传给this
- this指针存在内存的栈区
4. C++和C语言实现Stack对比
