
1 类的定义① 类是C中一种用户自定义类型它把数据成员和操作这些数据的成员函数封装在一起是创建对象的模板。类就是对“数据操作数据的方法”的封装是创建对象的模板。② 类中的变量称为类的属性或成员变量类中的函数称为类的方法或成员函数。类负责把“数据”和“操作数据党的方法”封装到一起访问限定符负责控制“谁能访问这些成员”。1.1 类定义格式1.2 访问限定符C中有三种访问限定符public、private和protected。①public成员可以被类内部、派生类以及类外部访问通常用来定义类对外提供的接口。②private成员只能由类自身的成员函数访问外部和普通派生类不能直接访问通常用于隐藏类内部实现和保护成员数据。③protected与private类似类外部不能直接访问但派生类可以访问因此主要用于继承。在实际设计种通常把成员变量设为private通过public成员函数对外提供操作接口实现封装并防止外部随意破坏对象内部状态。class定义成员没有被访问限定符修饰时默认privatestruct默认public。一个访问限定符会一直作用到下一个访问限定符出现为止。C 中的struct通常用于组织数据并经常通过typedef简化类型名而 C 对struct进行了扩展结构体名本身就是类型名同时struct可以包含成员变量、成员函数以及public/private/protected等访问限定符因此它和class已经非常接近最主要区别是struct默认public而class默认private。2 实例化2.1 实例化概念类是类型对象是类的一个具体实例是实际存在并占用内存空间的实体。类实例化对象就是根据类这个自定义类型创建一个具体对象的过程。类本身只是对成员变量和成员函数的定义相当于一种类型描述实例化之后得到的对象才是真正在程序运行中存在的实体并会占用内存空间。2.2 对象大小成员函数代码通常放在程序的代码区由所有对象共享。对象的大小主要由非静态成员变量决定而普通成员函数不会增加每个对象的大小。①空类也要占1字节主要是为了保证每个对象在内存中都有唯一、可区分的地址。如果空类对象大小为0那么创建多个空类对象时它们可能占用同一个内存位置就无法保证不同对象拥有不同地址。因此C编译器通常会给空类对象分配至少1字节的空间这个字节不是用来存成员数据的而是用来标识这个对象在类中确实存在。② 对象大小不包含普通成员函数。成员函数的机器指令只需要保存一份通常放在程序的代码段中由同一个类的所有对象共享执行而对象本身只需要保存各自独立的状态数据也就是非静态成员变量。对象存在的是“数据”成员函数存放的是“代码”代码共享数据独立所以普通成员函数不计入对象大小。3 this指针this是C普通非静态成员函数中一个隐含的指针它保存当前调用该成员函数的对象地址。编译器调用普通成员函数时会隐式地把当前对象的地址传过去。①this本身是一个常量指针不能让它重新指向其他对象但可以通过它修改当前对象的数据。谁调用成员函数this就指向谁成员函数通过this找到当前对象的数据。②this不是对象的成员变量不占对象空间并且静态成员函数中不存在this指针。③this指针本质上是成员函数的一个隐含参数所以它并不是固定存放在某“内存区域”中的成员变量。在现代C的实际调用约定下this往往优先通过CPU寄存器传递如果寄存器不够或编译器需要保存它也可能临时放到当前函数的栈帧中。之所以这样是因为this只在成员函数调用期间有意义用来告诉函数“当前操作的是哪个对象”它不属于对象本身因此不会存在对象所在的堆区或栈区中也不会加入sizeof(对象)。this不是像对象/变量那样“分配在某个内存区域”的实体而是成员函数被调用时由编译器隐式传入的当前对象指针值通常走寄存器/栈传参实现调用期存在它指向当前对象本身所在的位置。① 通过对象指针调用成员函数时指针会作为当前对象的地址传给隐藏的this指针。②如果对象指针是nullptr就不存在一个有效的当前对象。此时通过它调用非静态成员函数属于未定义行为一旦访问this-_a这样的成员通常就会因为非法访问内存而崩溃。③通过空指针调用非静态成员函数本身就属于未定义行为不能认为“只要函数里不访问成员变量就一定安全”。