多态:同一個方法在派生類和基類中的行為是不同的,方法的行為應取決于調用該方法的對象,即同一個方法的行為随上下文而異
- 在派生類中重新定義基類的方法
- 使用虛函數
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
- 基類聲明了一個虛析構函數,這樣做是為了確定釋放派生對象時,按正确的順序調用析構函數