day2面向对象编程
面向过程编程
- 关注问题解决的步骤,算法
面向过程编程
- 关注的是谁能解决问题(类),需要什么样的数据(成员变量),具备什么样的技能(成员函数),才能解决问题
抽象 找出一个能够解决问题的对象(观察研究对象),找出解决问题所必须的数据(属性),功能(成员函数)
封装 把抽象的结构归结为一个类(数据类型),然后实例化类对象,设置对象的属性,调用对象的功能达到解决问题的目的
继承 在解决问题前,先寻找之前的类能不能解决问题/部分问题,如果可以,则把旧的类继承后再次拓展,来缩短解决问题的时间,降低解决问题的难度
多态 一个对象的多种形态,外部看到一个对象,然后向对象发出指令,对象会根据自身的情况做出独特的反应
类和对象
- 通过分析"对象"的属性和行为设计出一个类
- 类就是数据类型
- 简单类型 只能表示一个属性(变量),C/C++内建数据类型
- 数组类型 可以表示多个属性(变量),类型必须相同
- 结构类型 可以表示多个属性(变量),但缺少行为(函数)
- 类类型 既能表示属性也能表示行为,一种符合数据类型
- 对象就是类这种数据类型创建出的实例,相当于结构变量
class Student
{
成员变量;
成员函数;
};
Student stu;
类的定义与实例化
- 类的一般形式
class 类名:继承方式 父类
{
public/private/protected://访问控制限制符
成员变量:
//构造函数
类名(形参表)
{
}
//析构函数
~类名(void)
{
}
};
- 类的访问控制限定符
public
公有成员,在任何位置都可以访问private
私有成员,只能类(自己)的成员函数中访问protected
受保护的成员,只能在类(自己)和子类中访问
注意 类中的成员变量,成员函数默认是private,结构中的成员变量,成员函数默认是public
注意 C++中类和结构的区别只有成员函数和成员变量的默认访问权限不同
- 构造函数
- 什么是构造函数:类的同名函数就是构造函数,没有返回值
- 什么时候被调用,谁调用,调用几次
- 创建类型对象时会被自己调用(每创建一个类对象就会被调用一次),对象的整个生命周期中定调用一次
- 负责干什么
- 成员变量的初始化,分配相关资源,设置对象的初始状态
class 类名:继承方式 父类
{
//构造函数
类名(形参表)
{
}
};
-
类型的创建过程
- 分配类型所需要的空间,无论是栈还是堆
- 传递实参调用构造函数,完成如下任务
- 根据继承表依次调用父类的构造函数
- 根据成员变量的顺序,一次调用成员变量的构造函数
- 执行构造函数体中的代码
注意 执行构造函数的代码时整个构造函数的最后一步,要保证构造函数代码所需要的一切资源和先决条件在该代码执行前已经准备充分,并得到正确的初始化
-
对象的销毁过程
- 在栈上创建:
类名 对象;
//不需要括号类名 对象(实参)
- 在堆上创建:
类名* 对象指针 = new 类名;
类名* 对象指针 = new 类名(实参);
- 创建多个对象:
类名 对象 = {(实参),(实参),(实参)};
类名* 对象指针 = new 类名[n]{类名(实参),类名(实参),类名(实参)};
注意 通过malloc创建的类对象不能调用构造函数
注意 通过new[]创建的对象,一定要通过delete[]释放
- 类的声明,实现,调用
- 在头文件中声明
class 类名 : 继承方式 父类 { 成员变量; public: //访问控制限制符 //构造函数 类名(形参表); //析构函数 ~类名(void); //其他成员函数 返回值 函数名(形参列表); };
- 源文件实现类的相关函数
返回值 类名::函数名(参数列表) { }
-
调用时只需要导入头文件,然后与类函数所在的源文件一起编译即可
注意 如果一个类的内容不多,可以考虑在头文件完全实现,也可以只在头文件实现一些简单的成员函数
注意 类中自动生成的函数,在源文件中实现时,也需要在头文件中声明
构造函数与初始化列表
- 构造函数可以被重载(同一个名字的函数有多个不同的版本)
- 无参构造是编译器自动生成的一个什都不做的构造函数(唯一的作用是避免编译错误)
注意 当类中实现一个缺省构造时,缺省构造就不会再生成了,如果有需要,必须显式地写出来 - 无参构造未必无参当有参构造的所有参数设置默认形参,调用这种构造函数就不需要传参
注意 所谓的"编译器生成的某某函数"其实不是真正语法意义上的函数而是功能意义上的函数,编译器作为可执行指令的生成者,会直接生成具有某项功能的二进制指令,不需要借助高级语言语义上的函数完成此项任务
注意 如果某个类是其他类的成员变量,那么一定要保证有一个无参构造,当B的构造函数执行时会先执行成员变量的无参构造,而此时类B是无法给类A的成员提供参数的
- 单参构造与类型转换
- 如果构造函数参数只有一个,那么
Test t = 20;
语句就不会出错,他会自动调用但惨构造来达到类型转换
如果要禁止这种类型转换需要在单参构造前加explicit
-
初始化列表
为类成员进行初始化用的
构造函数(参数):成员1(参数1),成员2(参数2),成员3(参数3)...
通过初始化列表可以给类成员变量传递参数,一次调用 类成员的有参构造
初始化列表也可以给const成员,引用成员进行初始化
成员的初始化顺序与初始化列表没有关系,而是与在类中的第一顺序有关
注意 初始化列表运行时,类成员变量还没有定义成功
实现C++链表
以C++ 的编程方式实现2048