一、什么是类和对象呢1、类的引入C 语言结构体中只能定义变量在 C 中结构体内不仅可以定义变量也可以定义函数。 比如 之前在数据结构初阶中用C 语言方式实现的栈结构体中只能定义变量 现在以 C 方式实现 会发现 struct 中也可以定义函数。2、类的定义1234classclassName{// 类体由成员函数和成员变量组成};// 一定要注意后面的分号class为定义类的关键字ClassName为类的名字{}中为类的主体注意类定义结束时后面分号不能省略。类体中内容称为 类的成员 类中的 变量 称为 类的属性 或 成员变量 ; 类中的 函数 称为 类的方法 或者 成员函数 。类的两种定义方式声明和定义全部放在类体中需注意成员函数如果 在类中定义 编译器可能会将其当成 内 联函数 处理。类声明放在 .h 文件中成员函数定义放在 .cpp 文件中注意 成员函数名前需要加类名 ::。3、类的访问限定符C实现封装的方式用类将对象的属性与方法结合在一块让对象更加完善通过访问权限选择性的将其接口提供给外部的用户使用。访问限定符说明public修饰的成员在类外可以直接被访问protected和private修饰的成员在类外不能直接被访问访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止如果后面没有访问限定符作用域就到 } 即类结束class的默认访问权限为privatestruct为public(因为struct要兼容C) 。4、类对象的储存方式我们假想每个对象中成员变量是不同的但是调用同一份成员函数如果按照每实例一个对象都给成员变量和成员函数创造一次空间存储当一 个类创建多个对象时每个对象中都会保存一份代码相同代码保存多次浪费空间。那么如何解决呢针对上面的问题类的存储就变成了只保存成员变量成员函数存放在公共的代码段 。那么一个类的大小其实就是实际就是该类中”成员变量”之和当然要注意内存对齐注意空类的大小空类比较特殊编译器给了空类一个字节来唯一标识这个类的对象。5、this指针的特性123456789101112131415161718192021222324252627classDate{public:voidInit(intyear,intmonth,intday){_year year;_month month;_day day;}voidPrint(){cout _year-_month - _day endl;}private:int_year;// 年int_month;// 月int_day;// 日};intmain(){Date d1, d2;d1.Init(2022,1,11);d2.Init(2022, 1, 12);d1.Print();d2.Print();return0;}我们知道了成员函数是放在了公共代码段。函数体中没有关于不同对象的区分。那么在上面的代码中d1和d2同时掉用了Print函数怎么是分别打印出d1对象中的成员变量和d2对象中的成员变量呢当然Init函数与Print函数的区分类似。C 中通过引入 this 指针解决该问题即 C 编译器给每个 “ 非静态的成员函数 “ 增加了一个隐藏 的指针参数让该指针指向当前对象 ( 函数运行时调用该函数的对象 ) 在函数体中所有 “ 成员变量 ” 的操作都是通过该指针去访问。只不过所有的操作对用户是透明的即用户不需要来传递编 译器自动完成 。如下图this指针的特性this 指针的类型类类型 * const 即成员函数中不能给 this 指针赋值this 指针是 “ 成员函数 ” 第一个隐含的指针形参一般情况由编译器通过 ecx 寄存器自动传递不需要用户传递this 指针本质上是 “ 成员函数 ” 的形参 当对象调用成员函数时将对象地址作为实参传递给this形参。所以 对象中不存储 this 指针只能在 “ 成员函数 ” 的內部使用。二、类的六个默认成员函数详解什么是默认成员函数呢默认成员函数用户没有显式实现编译器会生成的成员函数称为默认成员函数。如果一个类中什么成员都没有简称为空类。 空类中真的什么都没有吗并不是任何类在什么都不写时编译器会自动生成以下6 个默认成员函数构造函数析构函数拷贝构造赋值重载普通对象取地址const对象取地址。我们来看一下各个默认的成员函数的概念及实现。本篇我们先掌握构造函数和析构函数这两个时相对较为麻烦和重要的下篇我们会接着是西安剩余的默认成员函数以及类和对象剩余的重要的部分。1、构造函数构造函数是一个特殊的成员函数名字与类名相同,创建类类型对象时由编译器自动调用以保证每个数据成员都有 一个合适的初始值并且在对象整个生命周期内只调用一次。构造函数是特殊的成员函数需要注意的是构造函数虽然名称叫构造但是构造函数的主要任务并不是开空间创建对象而是初始化对象。其特征如下函数名与类名相同无返回值对象实例化时自动调用对应的构造函数构造函数可以重载。如果如果类中没有显式定义构造函数则C编译器会自动生成一个默认的无参构造函数一但用户显式定义编译器将不再生成。我们结合着以下代码一起理解以下。123456789101112131415161718192021222324252627classDate{public:// 1.无参构造函数Date(){}// 2.带参构造函数Date(intyear,intmonth,intday){_year year;_month month;_day day;}private:int_year;int_month;int_day;};voidTestDate(){Date d1;// 调用无参构造函数Date d2(2015, 1, 1);// 调用带参的构造函数// 注意如果通过无参构造函数创建对象时对象后面不用跟括号否则就成了函数声明// 以下代码的函数声明了d3函数该函数无参返回一个日期类型的对象// warning C4930: “Date d3(void)”: 未调用原型函数(是否是有意用变量定义的?)Date d3();}关于编译器生成的默认成员函数很多人都会有疑惑不实现构造函数的情况下编译器会 生成默认的构造函数。但是看起来默认构造函数又没什么用 象调用了编译器生成的默 认构造函数但是 对象中的成员函数 依旧是随机值。也就说在这里 编译器生成的 默认构造函数并没有什么用