类的定义
1.类的定义格式
一定要记住class这个关键字,它是定义类的关键字。
定义类的格式:class+类的名字+{内容}+;
一定要记住class定义完了后最后括号后面还有分号;
类里面可以包括成员变量和成员函数,比如
2.成员函数特性
定义在类里面的成员函数默认为inline,取决于编译器和你的成员函数的代码。意思就是说你在类里面放一个成员函数,看情况,有可能编译器会使你这个函数是一个内联函数,也有可能不会使你的函数成为一个内联函数,如果你的函数被认定为内联函数那么下次调用时就不开辟空间,直接在调用的地方直接展开,但是如果编译器不想将你的函数作为内联函数那么,这个成员函数就会作为一个普通函数,还是会开辟空间。
3.struct也可以定义类
struct也可以像class差不多定义类,格式我不多说了直接看代码。
4.访问限定符
访问限定符有三种分别是,public,private,protected。protected和private是一样的,现在还先不说它们之间的差异,
作用域:每个限定访问符的作用域都是从自身开始到下一个限定访问符结束,或者到“}”结束
在private作用域中的成员只能在类中访问,在类外访问会报错。
在public作用域中的成员可以在类中访问也可以在类外访问。
class定义的类如果没有写访问限定符那么默认是在private中
struct定义的类如果没有写访问限定符那么默认是在public中
5.类域
类域的作用就是每个类的成员都被类给包了起来,如果想用这个类里的成员就需要指明类的名字。我们直接看代码
以上代码就是类域的表现,对象+.+成员函数
如果我们不表明类域就会发生下面情况
编译会报错,因为不指明类域,编译器就会以为Add是全局函数,然后找不到它。
实例化对象
我们看上面的图来进行理解,如果类是一个图纸,那么用它造出来的东西就是对象
你们看这个,MyClass是类,而MC,MB,MA,MD就是用这个类造出来的对象,这个过程就是类的实例化,类是一个模型,用这个模型生产出来的就是对象。
1.对象大小
如何计算对象的大小??
我们先要判断计算对象的大小,那么对象的大小包括什么,包括成员函数??包括成员变量??
如果包括成员函数,我们要分析的是函数被编译后是一段指令,对象中没法储存,这些指令存储在一个单独的区域,如果对象非要储存那么储存的就是它的成员函数的指针,如果存了函数指针,调用100次类那么指针就要被重复100次,这样就太消耗空间了,那么成员函数有存指针的必要吗,其实函数指针是没有必要存储的,函数指针是一个地址,编译器在链接的时候,就要找到函数的地址,不是在运行找,所以对象中没必要存函数地址。
当我计算对象大小时我们直接计算成员变量大小即可。
2.内存对齐规则
1.第一个成员与结构体偏移量为0的地址处
2.其它成员变量要对其到某个数字(对其数)的整数倍的地址处
3.注意:对其数=编译器默认的一个对其数与该成员大小的较小值
4.VS中默认对其数是8
5.结构体总大小为:最大对其数(所有变量类型最大者与默认对齐参数取最小)的整数倍
6.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对其数的整数倍初,结构体的整体大小就是所有最大对其数(含嵌套结构体的对齐数)的整数倍。
7.如果对象没有成员变量那么对象的大小就是1,因为如果一个字节都不给,那对象不就跟没存在过吗,所以至少给一个字节,纯粹是让对象占个位置,证明它存在过。
this指针
用下面代码理解this指针
我们想想,当我们用Init对变量初始化的时候,编译器是怎么知道我们初始化的对象是谁??
这时就需要了解this指针了,其实MD类Init的原型是
void Init(MyClass* const this,int a,int b,int c)
这个this指针指向的就是这个 MD,所以类成员函数访问成员变量本质都是通过this指针访问的,如Init函数给_a赋值时就是
this->_a=a
但是C++规定不能在实参和形参位置显示的写this指针(编译时编译器会处理),但是可以在函数体内显示使用this指针