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