C++繼承三之純虛擬函式pure virtual function

gaopengtttt發表於2016-08-11
在C++中我們可以將一些類的共性編寫到一個抽象的類中叫他抽象類(ABC abstract base class)
這個類中必須包含一個純虛擬函式,抽象類不能定義出物件,但是可以作為其他類的基類。在抽象
類中可以對純虛擬函式進行定義也可以不定義,但是注意純虛擬函式一般是透過抽象類派生出來的派
生類的差異性函式原型,及不能在抽象類中實現的函式。那麼抽象類的特點為:
1、至少包含一個純虛擬函式
2、純虛擬函式可以定義也可以不定義,但是一般是派生類之間的差異函式不能實現的函式
3、抽象類不能用於定義物件,但是可以宣告抽象類的指標和引用
4、抽象類包含解構函式、建構函式。
5、純虛擬函式包含虛擬函式的所有特點,比如向上轉換時候基類指標自適應、透過vtbl
   (virtual function table)
   實現等。


那麼下面說明一下純虛擬函式,純虛擬函式可以包含定義也可以不包含定義,當然前面說過既然成為
純虛擬函式一般是不能在抽象類中實現的函式
實際上在虛擬函式原型中
後面加上 = 0 即可如:
vritual test(int a) = 0 ;
可以將抽象ABC類看做一種必須的介面,派生類覆蓋其純虛擬函式,這樣迫使派生類遵守
ABC類的介面規則,讓設計人員能夠制定介面約定,這樣確保從抽象ABC類繼承的所有的
派生類支援抽象類的約定的功能介面.
我們還是以C++ Primer Plus列子的標頭檔案作為說明

點選(此處)摺疊或開啟

  1. #include<iostream>
    #ifndef ACCTABC_H_
    #define ACCTABC_H_
    #include<string>
    using namespace std;


    class AcctABC
    {
            private:
                string fullName;
                    long acctNum;
                    double balance;
            protected:
                    struct Formatting
                    {
                            ios_base::fmtflags flag;
                        streamsize pr;
                    };
                    const string& FullName() const{
                            return fullName;
                    }
                    long AcctNum() const {
                            return acctNum;
                    }
                    Formatting SetFormat() const;
                    void Restore(Formatting& f) const;
            public:
                    AcctABC(const string& s="Nullbody",long an= -1,double bal= 0.0);
                    void Deposit(double amt);
                    double Balance() const{return balance;};
                    virtual void Withdraw(double amt) = 0; //pure virtual function
                    virtual void ViewAcct() const = 0;//pure virtual function
                    virtual ~AcctABC(){}
    };


    class Brass:public AcctABC
    {
            public:
                    Brass(const string& s="Nullbody",long an=-1,double bal = 0.0):AcctABC(s,an,bal){}
                    virtual void Withdraw(double amt); //redefine pure virtual function 
                    virtual void ViewAcct() const;     //redefine pure virtual function
                    virtual ~Brass(){};
    };


    class BrassPlus:public AcctABC
    {
            private:
                    double maxLoan;
                    double rate;
                    double owesBank;
            public:
                    BrassPlus(const string& s="Nullbody",long an = -1,double bal=0.0,double ml = 500,double r=0.10);
                    BrassPlus(const Brass& ba,double ml=500,double r=0.1);
                    virtual void ViewAcct() const;//redefine pure virtual function
                    virtual void Withdraw(double amt);//redefine pure virtual function
                    void ResetMax(double m){maxLoan=m;}
                    void ResetOwes(){owesBank=0;}
                    virtual ~BrassPlus(){}
    };
    #endif

顯然Brass和BrassPlus中包含了很多相同點,我們將他們
抽象出來,但是他們的不同點是
virtual void Withdraw(double amt);
virtual void ViewAcct() const;
實現的不同,並且brassPlus中多了一些資料成員
所以我們抽象出了AcctABC包含了共同點,
對實現不同的函式Withdraw和ViewAcct定義為
純虛擬函式
virtual void Withdraw(double amt) = 0; //pure virtual function
virtual void ViewAcct() const = 0;//pure virtual function
讓他隨後的繼承類中自己實現

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2123317/,如需轉載,請註明出處,否則將追究法律責任。

相關文章