一、面向对象和面向过程
面向过程:
关注如何解决问题,以及解决问题的步骤
面向对象:
关注的解决问题的"人"-"对象",以及实现能解决问题的"对象"
抽象:先找出(想象)能解决问题的"对象",分析该对象解决问题所需要的属性(成员变量)和行为(成员函数)
封装:把抽象的结果封装成一个类类型(结构),并给类的成员变量、成员函数设置相对应的访问控制权限(public\private\protected)
继承:
1、在封装类前先考虑现有的类是否能解决部分问题,如果有则可以通过继承,只需要在此基础上扩展即可,从而缩短解决问题的时间
2、把一个复杂的大问题拆分成若干个不同的小问题,给每个小问题设计一个类去解决,最后把这些类通过继承合并成一个能解决大问题的类,从而降低问题的难度
多态:
发出一个指令,系统会根据实际情况执行不同的操作,这种特征称为多态(一个指令多种形态)
比如重载过的函数、当调用函数时会根据参数的不同调用不同的版本,具体调用哪个版本在编译期间可以确定,称为编译时多态
注意:面向对象的细节的本质上还是面向过程,因此面向对象不是解决问题的捷径,而是以更高的维度去思考问题
二、类和对象
什么是类和对象
类是由程序员设计一种数据类型,里面包含有成员变量、成员函数
而对象就是类的实例化,可以理解为使用类类型创建的变量,创建的过程叫做实例化
类的设计和对象的实例化:
class 类名
{
成员变量; // 类中默认属性是private私有
public:
成员函数;
};
对象的实例化:
方法1: 类名 类对象名;
方法2: 类名* 类对象名_p = new 类名;
类的声明、实现、使用:
1、在头文件中声明:
class 类名
{
成员变量;
public:
返回值 成员函数名(参数列表);
};
2、在源文件中实现成员函数
返回值 类名::成员函数名(参数列表)
{
// 在成员函数中可以直接使用成员变量、成员函数
// 不需要使用 . -> 来表示访问
}
注意:如果类的内容不多,也可以直接在头文件中把成员函数实现
三、访问控制限定符
private
私有的,被它修饰的成员只能在类内访问,这是类的默认访问属性
设置为私有的是为了对类进行保护,一般会把成员变量设置私有
public
公开的,被它修饰的成员可以在任意位置访问
一般会把成员函数设置公开
protected
保护的,被修饰的成员只能在本类内和它的子类中访问,但不能在类外访问
四、构造函数
构造函数就是与类名同名的成员函数,当实例化对象时它会自动执行,当构造函数执行结束后,对象才完成实例化
任务:一般负责对类对象进行初始化、资源分配
class 类名
{
int* p;
public:
类名(参数)
{
p = new int;
}
};
1、构造函数必须是public,否则无法实例化对象
2、构造函数可以重载,可以有多个版本的构造函数(无参、有参)
3、带参数的构造函数的调用
类名 对象名(实参); // 使用实参调用有参构造
类名* 对象名 = new 类名(实参); // 使用实参调用有参构造
4、默认情况下编译器会自动生成一个什么都不干的无参构造函数,但一旦显式地实现了构造函数,就不再自动生成该无参构造函数了
5、如果给有参构造设置了默认形参,实例化对象时可以出现类似调用无参构造的语句,但实际是调用有参构造
6、构造函数没有返回值
7、不能使用malloc给类对象分配内存,因为它不会调用构造函数
五、析构函数
任务:析构函数一般负责对类对象内容进行收尾工作,例如:释放资源、保存数据等
当对象销毁时会自动执行
class 类名
{
int* p;
public:
类名(参数)
{
p = new int;
}
~类名(void)
{
delete p;
}
};
1、析构函数也必须是public
2、析构函数没有参数、没有返回值、不能重载
3、当类对象生命周期完结,被操作系统自动释放(栈),或者通过delete手动释放(堆) 才会调用析构函数
4、构造函数必定执行,但析构函数不一定会执行
5、不能使用free销毁类对象,因为不会调用析构函数
6、如果没有显式地实现析构函数,编译器也会自动生成一个什么都不做的析构函数
六、初始化列表
初始化列表是属于构造函数的一种特殊语法,只能在构造函数中使用
class 类名
{
const 成员1;
成员2;
public:
类名(参数) : 成员1(val),成员2(val) // 初始化语句 val可以是常量、变量
{
//成员1 = val; 属于赋值语句 不是初始化 带const属性的成员就无法赋值
}
};
注意:
1、初始化列表是先于构造函数执行,初始化列表执行时类对象还没有实例化完成,因此它是一种给const属性成员变量初始化的最佳方案
2、当参数名与成员名相同时,初始化列表可以分辨出来,可以同名
3、当成员中有类类型,该成员的有参构造函数可以在初始化列表中调用