一、概述
c++的virtual提供了運作時的多态,可以用基類的指針調用子類對象的函數,通過override可以強制要求基類有對應的虛函數。
二、測試代碼
#pragma once
#include <stdio.h>
class Base
{
public:
void A_1()
{
printf("Base::A_1\n");
};
virtual void A_2()
{
printf("Base::A_2\n");
}
virtual void A_3()
{
printf("Base::A_3\n");
}
virtual void A_4()
{
printf("Base::A_4\n");
}
void A_5()
{
printf("Base::A_5\n");
}
};
class Drived : public Base
{
public:
void A_1() //覆寫了基類的函數,用基類指針調用時調用到的時基類的A_1,用子類指針調用時調用到的時子類的A_1
{
printf("Drived::A_1\n");
};
virtual void A_2() //用基類或子類指針都調用到的是子類的A_2,之類的virtual說明的是是子類的A_2還可以被virtual
{
printf("Drived::A_2\n");
}
void A_3() //用基類或子類指針都調用到的是子類的A_2
{
printf("Drived::A_3\n");
}
virtual void A_4() override //子類加上override,如果基類沒有對應virtual函數就會編譯錯誤。避免拼錯和記錯沒有重寫基類函數
{
printf("Drived::A_4\n");
}
/*
void A_5() override //編譯錯誤 'Drived::A_5': method with override specifier 'override' did not override any base class methods
{
printf("Drived::A_5\n");
}
*/
};
class Drived2 : public Drived
{
public:
void A_2() override
{
printf("Drived2::A_2\n");
}
void A_3() override//用基類或子類指針都調用到的是子類的A_2
{
printf("Drived2::A_3\n");
}
};
class VirtualTest
{
public:
void DoTest()
{
Drived *drived = new Drived();
Base *base = drived;
base->A_1();
drived->A_1();
printf("\n");
base->A_2();
drived->A_2();
printf("\n");
base->A_3();
drived->A_3();
printf("\n");
base->A_4();
drived->A_4();
printf("\n");
Drived2 *drived2 = new Drived2();
base = drived2;
drived = drived2;
base->A_2();
drived->A_2();
drived2->A_2();
printf("\n");
base->A_3();
drived->A_3();
drived2->A_3();
}
};
三、輸出
Base::A_1
Drived::A_1
Drived::A_2
Drived::A_2
Drived::A_3
Drived::A_3
Drived::A_4
Drived::A_4
Drived2::A_2
Drived2::A_2
Drived2::A_2
Drived2::A_3
Drived2::A_3
Drived2::A_3
四、總結
1、基類函數沒加virtual,子類有相同函數,實作的是覆寫。用基類指針調用時,調用到的是基類的函數;用子類指針調用時,調用到的是子類的函數。
2、基類函數加了virtual時,實作的時重寫。用基類指針或子類指針調用時,調用到的都是子類的函數。
3、函數加上override,強制要求基本相同函數需要是虛函數,否則會編譯報錯。
4、子類的virtual可加可不加,建議加override不加virtual。