封装可以隐藏实现细节,使得代码模块化;
继承可以扩展已存在的代码模块(类);
它们的目的都是为了——代码重用。
而多态则是为了实现另一个目的——接口重用
封装就是将抽象得到的数据和行为相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成类,其中数据和函数都是类的成员,目的在于将对象的使用者和设计者分开,以提高软件的可维护性和可修改性
继承就是新类从已有类那里得到已有的特性。 类的派生指的是从已有类产生新类的过程。原有的类成为基类或父类,产生的新类称为派生类或子类,子类继承基类后,可以创建子类对象来调用基类函数,变量等
继承一个父类,这种继承称为单一继承,一般情况尽量使用单一继承,使用多重继承容易造成混乱易出问题
继承多个父类,类与类之间要用逗号隔开,类名之前要有继承权限,假使两个或两个基类都有某变量或函数,在子类中调用时需要加类名限定符如c.a::i = 1;
多重继承掺杂隔代继承1-n-1模式,此时需要用到虚继承,例如 B,C虚拟继承于A,D再多重继承B,C,否则会出错
继承方式规定了如何访问继承的基类的成员。继承方式指定了派生类成员以及类外对象对于从基类继承来的成员的访问权限
继承也分为接口继承和实现继承:
一个接口多种方法,即用同一个接口,但是效果不同
是指在程序运行时才能确定函数和实现的链接,此时才能确定调用哪个函数,父类指针或者引用能够指向子类对象,调用子类的函数,所以在编译时是无法确定调用哪个函数。
使用时在父类中写一个虚函数,在子类中分别重写,用这个父类指针调用这个虚函数,它实际上会调用各自子类重写的虚函数。
用virtual关键字修饰的函数;
本质上由虚指针和虚表控制,虚指针指向虚表中的某个函数入口地址,就实现了多态
含有至少一个纯虚函数的类叫抽象类,因为抽象类含有纯虚函数,所以其虚表是不健全的,在虚表不健全的情况下是不能实例化对象的,子类继承抽象基类后必须重写基类的所有纯虚函数。
否则子类仍为纯虚函数子类将抽象基类的纯虚函数全部重写后会将虚表完善,此时子类才能实例化对象,纯虚函数只声明不定义,形如 virtual void print() = 0
是在编译期就把函数链接起来,此时即可确定调用哪个函数或模板,静态多态是由模板和重载实现的,在宏多态中,是通过定义变量,编译时直接把变量替换,实现宏多态
优点: 带来了泛型编程的概念,使得C++拥有泛型编程与STL这样的武器; 在编译期完成多态,提高运行期效率; 具有很强的适配性和松耦合性,(耦合性指的是两个功能模块之间的依赖关系)
缺点: 程序可读性降低,代码调试带来困难;无法实现模板的分离编译,当工程很大时,编译时间不可小觑 ;无法处理异质对象集合