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、多態使用時,如果子類有屬性開闢到堆區,那麼父類指針在釋放時無法釋放子類的析構代碼,因此將父類中的析構函數改爲虛析構和純虛析構。有了純虛析構後,這個類也屬於抽象類