6.28隨筆(C++類的多態性和虛函數)

C++中類的多態性通過虛函數來實現

虛函數與純虛函數

虛函數

定義方法:在基類的函數前面加上virtual關鍵字
定義某個函數爲虛函數是爲了能夠使用基類指針來調用派生類函數

#include <iostream>
using namespace std;

class A
{
public:
    void print1()
    {
        cout << 1 << endl;
    }
    virtual void print2()
    {
        cout << 2 << endl;
    }
};
class B : public A
{
public:
    void print1()
    {
        cout << 3 << endl;
    }
    void print2()
    {
        cout << 4 << endl;
    }
};
int main()
{
    A a;
    B b;
    A *p;
    p = &a;
    p->print1();
    p->print2();
    p = &b; //基類指針指向派生類對象
    p->print1();
    p->print2();
    return 0;
}
示例

上面代碼輸出 1 2 1 4 ,前兩個很清楚,基類指針指向基類對象,調用的都是基類本身函數,自然輸出1 2
後面兩個輸出 1 4,體現了類的多態性,輸出1是因爲基類指針指向派生類對象,只會調用基類的函數(也即靜態綁定),輸出2的原因是因爲基類中的print2()是虛函數,由於每個虛函數都有一個虛函數列表,此時p調用print1()並不是直接調用函數,而是通過虛函數列表找到相應的函數的地址,因此根據指向的對象不同,函數地址也將不同,這裏將找到對應的子類的print1()函數的地址(也即動態綁定)。

純虛函數

定義方法:在虛函數後面加上=0
性質:

  1. 包含純虛函數的類稱爲抽象類,抽象類不可以創建對象。
  2. 純虛函數在基類中沒有定義,但是在派生類必須找到相應的實現方法,否則派生類也爲抽象類。
#include <iostream>
using namespace std;

class A
{
public:
    void print1()
    {
        cout << 1 << endl;
    }
    virtual void print2() = 0; //定義了一個純虛函數
};
class B : public A
{
public:
    void print1()
    {
        cout << 3 << endl;
    }
    void print2()
    {
        cout << 4 << endl;
    }
};
int main()
{
    // A a; //錯誤 A爲抽象類
    B b;
    A *p;
    p = &b; //基類指針指向派生類對象
    p->print1();
    p->print2();
    return 0;
}
示例

參考資料

  1. 淺談C++多態性
  2. 虛函數和純虛函數的區別
  3. C++父類指針指向子類對象的實現原理
  4. 當我們使用虛函數的時候,我們究竟想幹什麼?
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章