32、多态分为静态和动态两种。静态多态有函数重载、运算符重载;动态多态是派生类和虚函数实现运行时多态。静态多态的函数地址早绑定,编译阶段确定函数地址,动态多态的函数地址晚绑定,运行阶段确定函数地址。动态多态满足条件:(1)有继承关系;(2)子类重写父类的虚函数。动态多态使用:父类的指针或者引用来指向子类的对象。
重写是指函数返回值类型,函数名,参数列表完全一致。
33、当子类重写了父类的虚函数,那么子类中的虚函数表内部会替换成子类的虚函数地址。
34、纯虚函数语法:virtual 返回值类型 函数名(参数列表)=0;当类中有了纯虚函数,这个类也称为抽象类。抽象类无法实例化对象,子类必须重写抽象类中的纯虚函数,否则也属于抽象类。
#include<iostream>
#include<string>
using namespace std;
class Base
{
public:
//纯虚函数,Base为抽象类
virtual void func() = 0;
};
class Son:public Base
{
public:
virtual void func()
{
cout << "func函数调用" << endl;
}
};
void test01()
{
Base* base = new Son;
base->func();
}
int main()
{
test01();
system("pause");
return 0;
}
35、多态案例:制作饮品
#include<iostream>
#include<string>
using namespace std;
class AbstractDrinking
{
public:
//煮水
virtual void Boil() = 0;
//冲泡
virtual void Brew() = 0;
//倒入杯中
virtual void PourInCup() = 0;
//加入辅料
virtual void PutSomeThing() = 0;
//制作饮品
void makeDrink()
{
Boil();
Brew();
PourInCup();
PutSomeThing();
}
};
//制作咖啡
class Coffee :public AbstractDrinking
{
//煮水
virtual void Boil()
{
cout << "煮水" << endl;
}
//冲泡
virtual void Brew()
{
cout << "冲泡咖啡" << endl;
}
//倒入杯中
virtual void PourInCup()
{
cout << "倒入杯中" << endl;
}
//加入辅料
virtual void PutSomeThing()
{
cout << "加入糖和牛奶" << endl;
}
};
//制作茶叶
class Tea :public AbstractDrinking
{
//煮水
virtual void Boil()
{
cout << "煮矿泉水" << endl;
}
//冲泡
virtual void Brew()
{
cout << "冲泡茶叶" << endl;
}
//倒入杯中
virtual void PourInCup()
{
cout << "倒入杯中" << endl;
}
//加入辅料
virtual void PutSomeThing()
{
cout << "加入枸杞" << endl;
}
};
//制作函数
void doWork(AbstractDrinking* abs)//AbstractDrinking *abs = new Coffee
{
abs->makeDrink();
delete abs;//释放
}
void test01()
{
doWork(new Coffee);
cout << "__________________" << endl;
doWork(new Tea);
}
int main()
{
test01();
system("pause");
return 0;
}
36、多态使用时,如果子类有属性开辟到堆区,那么父类指针在释放时无法释放子类的析构代码,因此将父类中的析构函数改为虚析构和纯虚析构。有了纯虚析构后,这个类也属于抽象类