純虛擬函式和抽象基類
阿新 • • 發佈:2019-01-03
在虛擬函式宣告的引數列表後面加上“=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是一個抽象類