目录
一、类的概念
二、类的引入
三、类的定义
1.定义一个类
2.struct 和 class 的区别
3.类中成员函数的声明、实现分离
四、封装及类的访问限定符
1.封装
2.类的访问限定符
五、类的作用域和生命周期
六、类的实例化
七、类存储方法
八、计算类的大小
一、类的概念
1.是什么?
是对有相同属性和行为的事物的抽象。
2.为什么?
把有关联的数据和函数放在一起方便管理,且类是面向对象编程的前提。
3.怎么用?
把要描述的事物的属性和行为(用函数实现)放在一起形成一个类。
二、类的引入
1.struct升级为类
在C++中 struct 不但兼容C语言中结构体的语法,而且 struct 在C++中升级成了类。
2.类中能定义函数
类包含两个部分成员变量、成员函数。所以在C++中,结构体内不仅可以定义变量,也可以定义函数。
3.class也能定义类
除struct外,C++中还能使用class来定义类,在C++中更常用class来定义类。
拓:struct 在 C 和 C++ 中的细微区别
1.C中使用typedef重命名结构体在,最后一行之后才生效,结构体中使用结构体名也必须带上struct。
2.C++中甚至不需要使用typedef重命名就可直接在类中使用类名。
三、类的定义
1.定义一个类
class className //法一 {// 类体:由成员函数和成员变量组成}; // 一定要注意后面的分号struct structName //法二 {// 类体:由成员函数和成员变量组成}; // 一定要注意后面的分号
class(或struct)为定义类的关键字,className(structName)为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。
2.struct 和 class 的区别
C++中既可以使用struct定义类,也可以使用class定义类,二者的区别在于:
在不加限定符的情况下,struct默认为公有,class默认为私有。
拓: 类的访问限定符
3.类中成员函数的声明、实现分离
a. 成员函数的 声明和实现 全部放在类体中,需注意:成员函数如果在类中定义,编译器 可能 会将其当成内联函数处理。
b. 成员函数的声明放在.h文件中,成员函数实现放在.cpp文件中。(注意:当声明和实现分离时,因为声明在类域中,故定义时 成员函数名前需要加上 类名和域作用限定符(::),才能找到该类。 )
在大型项目中推荐把类中成员函数和普通函数一样,将声明和实现分离,类中成员函数声明和定义分离的意义在于方便阅读代码。
拓1、成员函数如果在类中定义,编译器可能会将其当成内联函数处理。
声明和实现分离后,类的成员函数就不会再被当成内联函数了。(内联函数的声明和实现不能分离,内联函数不会进符号表,链接时靠声明无法找到实现的地址)
拓2、在声明和定义分离时:如果定义时中我们不加类的域名,这时类域中和全局域中就会出现两个同名函数,这是可行的且不构成函数重载。(在不同域中的函数不构成重载)
四、封装及类的访问限定符
1.封装
1.是什么?
本质上是对数据的管理:隐藏对象的属性和方法的实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别。
2.为什么?
提高程序的安全性和可维护性(改进的难易程度)。
3.怎么做?
C++实现封装的方式:用类将属性与方法结合在一块,通过设置访问权限选择性的将其接口提供给外部的用户使用。
2.类的访问限定符
public(公有)、private(私有)、protected(保护)
五、类的作用域和生命周期
1.类的作用域
类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用 :: 作用域操作符指明成员属于哪个类域。
2.类的生命周期
类的生命周期和存储位置有关,如:全局的类和静态的类存储在静态区,它的生命周期就是整个工程,在函数中的类,生命周期随着这个函数……
六、类的实例化
用类创建对象的过程,称为类的实例化。一个类可以实例化出多个对象。
类不占空间,实例化成对象后才会占用空间,用于存储类成员变量。但是我们也可以通过类计算对象占用的空间大小。
同理,定义结构体不占空间,定义结构体变量才会占用空间,但是我们也可以使用sizeof结构体名来计算结构体变量占用的空间大小。
七、类存储方法
类存储方法猜想一:将成员函数的地址和成员变量都存起来
存在问题:调的成员函数都是一样的,所以没必要都每个对象都存一个成员函数的地址
类存储方法猜想二:将成员函数的地址单独存放进一张表中,然后存储时多存一个表的地址
这种方法没有什么问题,但在这里没有被采用。
类存储方法猜想三:只存成员变量,将成员函数统一存放在公共代码区。
这个方案就是类的存储方案,运行时不会在对象中找函数的地址,编译链接时才会根据函数名去公共代码区找到函数的地址。
所以类在遇到如下情况,程序不会崩溃。(因为找成员函数的地址不是在类中找,是去公共代码区找,所以类被实例化为nullptr我们依然能够调用成员函数)
八、计算类的大小
1.计算成员变量的大小
类和结构体的一样,也遵守内存对齐规则,从第二个成员变量开始,起始位置要计算,在自己的大小和默认对齐数(VS编译器中默认对齐数为8)中选择较小的那个。最后整个类也必须要对齐:类的大小必须是默认对齐数的整数倍。
2.计算成员函数的大小
算类的大小时,不用考虑成员函数,故不用加上函数指针的大小。
3.计算空类的大小
注意,没有成员变量的类(包括空类)的大小为1字节,不存储数据,目的是为了占位,标识对象存在,区分不同的对象。
总结:
计算类的大小就是按照内存对齐的方式计算成员变量的方法。