多态:同一个方法在派生类和基类中的行为是不同的,方法的行为应取决于调用该方法的对象,即同一个方法的行为随上下文而异
- 在派生类中重新定义基类的方法
- 使用虚函数
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
- 基类声明了一个虚析构函数,这样做是为了确保释放派生对象时,按正确的顺序调用析构函数