天天看點

多态公有繼承

多态:同一個方法在派生類和基類中的行為是不同的,方法的行為應取決于調用該方法的對象,即同一個方法的行為随上下文而異

  • 在派生類中重新定義基類的方法
  • 使用虛函數
class Brass
{
private:
    std::string fullName;
    long acctNum;
    double balance;
public:
    Brass(const std::string & s = "Nullbody",
          long an = -1,
          double ba1 = 0.0);
    virtual ~Brass();
    void Deposit(double amt);
    double Balance() const;
    //==================================
    virtual void Withdraw(double amt);
    virtual void ViewAcct() const;   
    //==================================
}

class BrassPlus : public Brass
{
private:
    double maxLoan;
    double rate;
    double oweBank;
public:
    BrassPlus(const std::string & s = "Nullbody",
              long bal = 0.0, double ml = 500,
              double r = 0.11125);
    BrassPlus(const Brass & ba, double ml = 500,
              double r = 0.11125);
    //==================================
    virtual void Withdraw(double amt);
    virtual void ViewAcct() const;
    //==================================
    void ResetMax(double m)
    {
        maxLoan = m;
    }
    void ResetRate(double r)
    {
        rate = r;
    }
    void ResetOwes()
    {
        owesBank = 0;
    }
}      
  • 類​

    ​Brass​

    ​和類​

    ​BrassPlus​

    ​都定義了​

    ​Withdraw()​

    ​和​

    ​ViewAcct()​

    ​方法,程式将根據對象類型來确定使用哪個版本:
Brass dom("Dominic Banker",11224,4183.25);
BrassPlus dot("Dominic Banker",12118,2590.25);
dom.ViewAcct(); //invoke Brass::ViewAcct()
dot.ViewAcct(); //invoke BrassPlus::ViewAcct()      
  • 如果方法是通過引用或指針而不是對象調用的,它将确定使用哪一種方法。如果沒有使用關鍵字virtual,程式将根據引用類型或指針類型選擇方法;如果使用了virtual,程式将根據引用或指針指向的對象的類型來選擇方法。
  • 如果ViewAcct()不是虛的,則程式的行為如下:
Brass dom("Dominic Banker",11224,4183.25);
BrassPlus dot("Dominic Banker",12118,2590.25);
Brass & b1_ref = dom;
Brass & b2_red = dot;
b1_ref.ViewAcct(); //invoke Brass::ViewAcct()
b2_red.ViewAcct(); //invoke Brass::ViewAcct()      
  • 如果ViewAcct()是虛的,則程式的行為如下:
Brass dom("Dominic Banker",11224,4183.25);
BrassPlus dot("Dominic Banker",12118,2590.25);
Brass & b1_ref = dom;
Brass & b2_red = dot;
//invoke Brass::ViewAcct()
b1_ref.ViewAcct(); 
//invoke BrassPlus::ViewAcct()
b2_red.ViewAcct();      
  • 方法在基類中被聲明為虛的後,它在派生類中将自動成為虛方法,當然也可以在派生類中使用關鍵字​

    ​virtual​

    ​來指出哪些函數是虛函數
  • 基類聲明了一個虛析構函數,這樣做是為了確定釋放派生對象時,按正确的順序調用析構函數