1. 程式人生 > >純虛擬函式和抽象基類

純虛擬函式和抽象基類

在虛擬函式宣告的引數列表後面加上“=0”;

    class C
    {
        virtual void f() = 0;
    };

就將使該函式變成純虛擬函式。我們在此不需要為純虛擬函式 C::f()提供任何的定義。那些宣告(或繼承)了純虛擬函式的類就是抽象基類。任何試圖建立一個抽象基類物件的操作都將導致編譯期錯誤的產生。

如果一個類派生自C並重寫了C::f,它就將成為具體類:

    class D : public c
    {
        void f();
    };

我們通常都將抽象基類用於介面的宣告,這時我們不需要為該介面宣告一個完整的實現。該介面描述了所有派生自該類的物件都應該支援的抽象操作;派生類必須實現這些抽象操作。例如:

    class Vehicle
    {
    public:
        virtual double accelerate(double) = 0;
        virtual double speed() = 0;
    };

由於Vehicle是一個抽象類,任何建立Vehicle物件的嘗試都會導致編譯期錯誤的產生: Vehicle v;//編譯期錯誤:“Vehicle”是抽象類

為了使用Vehicle,我們必須從它從它派生出其它的具體類:

   class Car : public Vehicle
    {
    public:
        virtual double accelerate(double);
        virtua; double speed();
    };
    
    class Bicycle : public Vehicle
    {
    public:
        virtual double accelerate(double);
        virtua; double speed();
    };

由於在Car和Bicycle眾,基類中的所有純虛擬函式都被重寫了,所以我們就可以得到由這兩個類構建出來的物件。

即使我們得不到Vehicle物件,我們仍然可以使用指向Vehicle的指標和引用;

   void
    full_stop(Vehicle& v)
    {
        v.accelerate(-v.speed());
    }

一個繼承(而沒有重寫)了純虛擬函式的類同樣也是一個抽象類:
    class Land_vehicle : public Vehicle
    {
    };
    
    Land_vehicle v;  //編譯期錯誤:Land_vehicle是一個抽象類