前面學習了多態底層原理和多態練習,這篇學習什麼是純虛函數和抽象類。虛函數前面我們介紹過,一個普通的類成員函數前面添加關鍵字virtual就變成一個虛函數。會有虛函數指針指向虛函數列表的概念,這裏純虛函數肯定和虛函數是有關係的。
1.虛函數的定義
語法是 virtual 返回值類型 函數名稱() = 0;
例如,下面這個代碼
class Base
{
public:
virtual void myFunc() = 0;
};
一般來說,在使用多態機制的時候,基類中的虛函數裏面沒不需要寫什麼實現,因爲寫了也很少用到。就前面動物的例子,虛函數打印 動物在叫,但是我們一般都是打印 貓在叫或者狗在叫,一般是派生類的同名函數中實現纔是我們關心的內容。
既然虛函數內部函數體沒有啥作用,所以就產生了純虛函數,寫法就像上面這個樣子。也就是在原來虛函數改成,刪除{}這大括號裏面內容,直接在函數名稱後寫 = 0;
2.抽象類的定義
在一個類中,只要有一個純虛函數,那麼這個類就叫抽象類。
class Base
{
public:
virtual void myFunc() = 0;
};
上面這個類,由於有一個純虛函數,所以Base類就是一個抽象類。抽象的字面意思就是抽出象的東西,一般這種抽取的東西都不詳細,不清晰,所以抽象。
3.抽象類特點
3.1 抽象類不能被實例化
就是不能在棧內存或堆內存創建抽象類的對象
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
virtual void myFunc() = 0;
};
void test01()
{
Base b; // 棧內存創建Base對象
new Base(); //堆內存創建Base對象
}
在上面函數 test01中兩種創建對象的方式都失敗,編譯器提出錯誤
3.2 子類必須實現基類的純虛函數
如果一個抽象類被一個派生類繼承,那麼在派生類中必須要實現純虛函數。
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
virtual void myFunc() = 0;
};
class Son : public Base
{
public:
};
void test01()
{
Son s;
}
int main()
{
test01();
system("pause");
}
上面子類沒有實現父類的純虛函數,在子類實例化的時候會報錯。
由於沒有實現父類的純虛函數,那麼子類也變成一個抽象類,有回到上抽象類不能實例化的問題。
接下來看看,正常子類實現父類純虛函數的代碼
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
virtual void myFunc() = 0;
};
class Son : public Base
{
public:
void myFunc()
{
cout << "子類必須實現父類的純虛函數" << endl;
}
};
void test01()
{
Base * b = new Son;
b->myFunc();
}
int main()
{
test01();
system("pause");
}
運行結果(VS code截圖)