Enter opening balance: $688

Enter opening balance: $688
Enter 1 for Brass Account or 2 for BrassPlus Account: 1

Client: Harry Fishsong
Account Number: 112233
Balance: $1500.00

Client: Dinah Otternoe
Account Number: 121213
Balance: $1800.00
Maximum loan: $350.00
Owed to bank: $0.00
Loan Rate: 12.00%

Client: Brenda Birdherd
Account Number: 212118
Balance: $5200.00
Maximum loan: $800.00
Owed to bank: $0.00
Loan Rate: 10.00%

Client: Tim Turtletop
Account Number: 233255
Balance: $688.00

Done.

多态特性是由下述代码提供的:
for (i = 0: i < CLIENTS: i++)

p_clients[i]->ViewAcct ():
cout << endl:

如果数组成员指向的是Brass对象,则调用Brass :: ViewAcct();如果指向的是BrassPlus对象,则调用
BrassPlus :: ViewAcct()。如果 Brass :: ViewAcct()被声明为虚拟的,则在任何情况下都将调用
Brass :: ViewAcct () .

4. 为何需要虚拟析构函数
在程序清单13.10中,使用delete释放由new分配的对象的代码说明了为何基类应包含一个虚拟析构
函数,虽然有时好像并不需要析构函数。如果析构函数不是虚拟的,则将只调用对应于指针类型的析构函
数。对于程序清单13.10,这意味着只有Brass的析构函数被调用,即使指针指向的是一个BrassPlus对象。
如果析构函数是虚拟的,将调用相应对象类型的析构函数。因此,如果指针指向的是BrassPlus对象,将调
用BrassPlus的析构函数,然后自动调用基类的析构函数。因此,使用虚拟析构函数可以确保正确的析构函
数序列被调用。对于程序清单13.10,这种正确的行为并不是很重要,因为析构函数没有执行任何操作。但
是,如果BrassPlus包含一个执行某些操作的析构函数,则Brass必须有一个虚拟析构函数,即使该析构函
数不执行任何操作。

13.4.2 静态联编和动态联编

程序调用函数时,将使用哪个可执行代码块呢?编译器负责回答这个问题。将源代码中的函数调用解
释为执行特定的函数代码块被称为函数名联编(binding)。在C语言中,这非常简单,因为每个函数名都
对应…个不同的函数。在C++中,由于函数重载的缘故,这项任务更复杂。编译器必须查看函数参数以及
函数名才能确定使用哪个函数。然而,C/C++编译器可以在编译过程完成这种联编。在编译过程中进行联
编被称为静态联编(static binding),又称为早期联编(early binding)。不过,虚函数使这项工作变得更困
难。正如在程序清单13.10所示的那样,使用哪一个函数是不能在编译时确定的,因为编译器不知道用户