下面是对“类和对象相关知识的总结",有需要借鉴即可。
1.面向过程与面向对象的初步认识
C语言是面向过程的语言,需要关注事物的发展过程,往往比较繁杂。
C++是面向对象且兼容面向过程的语言,侧重于关注不同对象,使用起来更加便捷。
既然C++面向对象可以提供许多便捷,那CPP也引入了相应的具体语法:
2.类
一个面向过程的语言往往思考比较困难,因而CPP引入了”类“的概念
为了支持类语法,CPP分别进行了语法升级和引入新语法
- 一方面CPP对struct进行了升级
- 1.cpp中的struct可以兼容C的结构体语法
- 2.cpp中的struct可以包含类的成员变量、成员函数
- 另一方面也单独引入了一个新的语法,类。
2.1类的概念
类是对对象描述的一种未填属性的模板,没有实际的内存空间
2.2类的声明
2.2.1概念:
CPP规定,类语法有两种声明形式:struct/class
2.2.2语法:
两种声明形式的区别:
- 1.struct兼容C的结构体语法,class是一种CPP专有新语法
- 2.默认情况下,struct成员变量/函数为公开状态,class成员变量/函数为私有状态。
建议:类成员的命名规则:
我们一般建议成员变量名称前置下划线
为什么要建议实行这种类的命名规则?
为了避免成员变量名称与成员函数参数名称的混淆
但是,类的声明仅仅是告诉编译器有这么一个“模板”,想要使用类,不光要有类的声明,还得需要类的定义以及类的访问。
2.3类的定义(类实例化)
前面提到过,类只不过是一种空白的模板而已,并不在内存中实际存在,因而要想使用类,首先要实例化出一个实际存在的类来,我们把这个过程称为“类的对象实例化”,把这个具体的实例化事物称之为“类对象”。
2.3.1概念:
按照类这个“模板”在内存中实际开辟空间,通常我们称之为“类的实例化”。
eg:Date d1;
2.4类的访问
2.4.1概念:通过类的实例化,对类对象进行访问。
在具体往下说的话,我们需要谈到“封装”这种管理方式了。
2.4.2封装:
封装概念:
将类中的成员变量/函数通过针对性的对外隐藏所实现的一种隐藏细节的管理方式。
CPP中为了实现对类的封装管理,引入了新的语法:访问限定符
访问限定符:
那封装的意义何在呢?
封装的意义:
能够有效规范化程序,可以有效降低程序规范性对程序员个人素质的依赖。
2.4.3类的访问格式:
类对象 + 点 + 成员变量/函数
3.类对象的存储原理
类对象到底在内存中怎么进行存储的呢?这就来到了类对象的“存储模型”了。
3.1类对象模型
对于成员变量,单独存放在栈帧中,而成员函数为了节省空间的考量,而放到了公共代码区所有类对象共享。
通过上面的类对象模型我们知道,类对象中成员变量是分开存储的,而类对象中的函数是共用一份的,那么其大小改如何进行计算呢?---->类对象的大小由类成员变量决定。
3.2类对象大小的计算
3.2.1计算规则:
类成员大小的计算遵循下面两条规则
- 只计算类对象中成员变量的大小
- 遵循内存对齐原则
3.2.2计算示例:
思考:内存对齐会浪费空间,那为什么还要进行内存对齐呢?
主要是为了效率的考量
- 1.硬件规定,每次cpu读取的大小为4/8字节
- 2.且需要从内存整数倍开始读
内存对齐是一种以空间换时间的行为,主要是为了效率的考量。
我们上面了解到,成员变量是存储在内存栈中的,而成员函数为了节省内存空间的考量是放在公共代码区的,那成员函数是怎么拿到成员变量的呢?
其实,为了解决成员函数拿到类对象中的值的问题,成员函数中隐藏了特殊的指针,this指针,指向整个类对象。
4.类成员函数中隐藏的this指针
4.1this指针的隐藏性
从代码表面上看,并没有所谓的this指针,但是实际上是有的,如下图:
那类成员函数是如何通过this指针来拿到类成员变量中的值的呢?
下面是类成员函数逻辑访问图:
4.2this指针的特性
- 1.我们不能把this指针写出来,这工作属于编译器。
- 2.this指针可以在成员函数内部使用。
- 3.this指针指向不可更改
思考:this指针存放在哪个存储区?
堆/栈/对象内/静态区/常量区???
this指针式作为函数第一个形参来存放在函数栈帧中的。
4.3对类对象存储原理的理解
- 1.类对象的成员变量是存放在类对象地址指向的区域的,因而需要有效的地址。
- 2.类对象的成员函数是存放在公共代码区的,调用此函数不需要类对象地址。
5.练习题:
EOF