多态:多种状态,多种形态,多种功能 一个函数具有不同的参数,就有不同的功能。
一、c++多态分为:
静态多态:程序在编译阶段,已经知道将要执行的状态。(函数重载,运算符重载,模板)。
动态多态:程序在运行阶段,才能确定要执行的状态。(继承,虚函数覆盖,基类复用状态)。 c++函数重载定义 :
1、通过相同的函数名 。
2、通过函数的参数列表不同 (个数不同,类型不同)。
3、返回值不能作为重载的条件。
c++重写: 也叫覆盖,是针对父类中的虚函数而言,如果子类中重新定义了父类中的virtual修饰的虚函数,叫做重写。
多态和重载的区别:
1、多态是建立在重写的基础之上的,是类与类之间的关系,而重载必须在同一个类中。
2、多态是动态的,属于动态联编,发生在运行阶段。重载是静态的多态,属于静态联编,发生在编译阶段。
二、虚表指针(*vptr,virtual)
1、虚函数虚表指针永远是储存在对象是首地址中。(它和数据成员的顺序无关)
2、virtual ,含有虚方法,系统就会创建一个 *vptr 指针,指向系统中的虚表。
3、所有的虚函数,都存储在系统的虚表中。
4、virtual void show(){} //虚函数
5、子类会把父类的虚表指针也继承下来,子类与父类共用虚表(实现覆盖)。
三、动态多态 要求:
1、基类要有虚函数。
2、派生类重写基类的虚函数。
3、通过基类的指针或引用指向派生类的对象,并调用重写后的接口。 缺一不可。
问:什么时候使用动态多态? 答:想要一个函数实现不同的功能时,就采用动态多态的设计方式。
例如:设计一个运动会函数,设计一个攻击函数,设计一个小卖部函数 。 不同的运动员,运动的内容不一样,不同的装备打车的攻击效果不一样,不同的商品售卖的价格不一样。
例子:设计一个攻击函数,根据不同的装备打出不同的攻击特效
四、纯虚函数与抽象类 纯虚函数的定义:
1、virtual 函数返回类型 函数名(参数表)=0; //纯虚函数 virtual void show()=0;
2、当一个类中含有一个纯虚函数,那么这个类就是抽象类!
3、抽象类不能定义对象。(不能实例化)
4、当这个类变成抽象类,它的子类也不能定义对象。
5、当一个函数覆盖纯虚函数,这个类就不是抽象类了。
6、抽象类的作用是说明这个类要实现动态多态。
#include
using namespace std;
//多态的基本语法
//在父类中必须加上virtual关键字(变成虚函数)
class Animal
{
public:
virtual void speak()
{
cout << "动物在说话" <
虚析构
#include
using namespace std;
class base {
public:
base() {cout << "base构造函数" << endl; }
virtual ~base(){cout << "~base析构函数" << endl;}
};
class xbase:public base {
public:
xbase() {cout << "xbase构造函数" << endl;
p = new int;
cout << "p->new分配堆空间"<< p << endl;
}
~xbase(){cout << "~xbase析构函数" << endl;
cout << "p -> 释放堆空间"<< p << endl;
delete p;
}
private:
int *p;
};
void test(base *p){
delete p;
}
int main()
{
test(new xbase);
}