静态多态:函数重载和运算符重载属于静态多态,复用函数名。函数地址早绑定——编译阶段确定函数地址。
动态多态:派生类和虚函数实现运行时多态。函数地址晚绑定——运行阶段确定函数地址。
class Animal
{
public:
//虚函数,地址晚绑定
virtual void speak()
{
cout << "动物说话" << endl;
}
};
class Cat :public Animal
{
public:
void speak()
{
cout << "cat说话" << endl;
}
};
//地址早绑定,动物说话
//如果想猫说话,就要地址晚绑定
void dospeak(Animal& animal)
{
animal.speak();
}
void test()
{
Cat cat;
dospeak(cat);
}
动态多态满足条件:
1,有继承关系
2,子类重写父类的虚函数
纯虚函数和抽象类
纯虚函数语法:
当类中有了纯虚函数,这个类也称为抽象类。
抽象类特点:无法实例化对象。子类必须重写抽象类中的纯虚函数,否则也属于抽象类
多态应用示例:
#include<iostream>
#include<string>
using namespace std;
//基类
class AbstractDrink
{
public:
//纯虚函数
virtual void Boil() = 0;
virtual void Brew() = 0;
virtual void Pour() = 0;
virtual void Put() = 0;
void MakeDrink()
{
Boil();
Brew();
Pour();
Put();
}
};
class Coffee :public AbstractDrink
{
//子类重写纯虚函数
virtual void Boil()
{
cout << "煮水" << endl;
}
virtual void Brew()
{
cout << "冲泡咖啡" << endl;
}
virtual void Pour()
{
cout << "倒入杯中" << endl;
}
virtual void Put()
{
cout << "放入糖和牛奶" << endl;
}
};
class Tea :public AbstractDrink
{
//子类重写纯虚函数
virtual void Boil()
{
cout << "煮水" << endl;
}
virtual void Brew()
{
cout << "冲泡茶叶" << endl;
}
virtual void Pour()
{
cout << "倒入杯中" << endl;
}
virtual void Put()
{
cout << "放入柠檬" << endl;
}
};
void dowork(AbstractDrink * abs)
{
abs->MakeDrink();
delete abs;
}
void test1()
{
//制作咖啡
cout << "制作咖啡" << endl;
dowork(new Coffee);
//制作茶
cout << "----------------" << endl;
cout << "制作茶" << endl;
dowork(new Tea);
}
int main()
{
test1();
system("pause");
return 0;
}
虚析构和纯虚析构
使用多态时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码。这时将父类中的析构函数改为虚析构或纯虚析构。
虚析构和纯虚析构的共性:
1,可以解决父类指针释放子类对象。如果子类中没有堆区数据,就可以不写。
2,都需要有具体的函数实现
虚析构语法:
纯虚析构语法: