上一个例子usebrass1.cpp中,方法是通过对象(而不是指针或者引用)来调用的,这个很清楚,也没有使用上虚函数的特性。本例子可以说明虚函数的使用场景和特点。
数组中所有元素的类型必须相同,而Brass 和BrassPlus是不同的类型。但是可以创建指向Brass的指针数组,这样每个元素的种类都相同,由于使用的是公有继承,指向Brass的指针也可以指向BrassPlus对象。
本例子的brass.h和brass.cpp 和usebrass1.cpp是一样的,这里就略过了。
usebrass2.cpp
// Chapter13.3usebrass2.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include "brass.h"
const int CLIENTS = 4;
int main()
{
// std::cout << "Hello World!\n";
using std::cin;
using std::cout;
using std::endl;
Brass* p_clents[CLIENTS];
std::string temp;
long tempnum;
double tempbal;
char kind;
for (int i = 0; i < CLIENTS; i++)
{
cout << "Enter client's name: ";
getline(cin, temp);
cout << "Enter client's account number: ";
cin >> tempnum;
cout << "Enter opening balance : $";
cin >> tempbal;
cout << "Enter 1 for Brass Account or" << "2 for BrassPlus Account: ";
while (cin >> kind && (kind != '1' && kind != '2'))
cout << "Enter either 1 or 2: ";
if (kind == '1')
p_clents[i] = new Brass(temp, tempnum, tempbal);
else
{
double tmax, trate;
cout << "Enter the overdraft limit: $";
cin >> tmax;
cout << "Enter the interest rate " << "as a decimal fraction:";
cin >> trate;
p_clents[i] = new BrassPlus(temp, tempnum, tempbal, tmax, trate);
}
while (cin.get() != '\n')
continue;
}
cout << endl;
for (int i = 0; i < CLIENTS; i++)
{
p_clents[i]->ViewAcct();
cout << endl;
}
for (int i = 0; i < CLIENTS; i++)
{
delete p_clents[i];//free memory
}
cout << "Done.\n";
return 0;
}
运行的时候需要一些交互式的输入,书上是这样输入的:
Harry Fishsong
112233
1500
1
Dinah Otternoe
121213
1800
2
350
0.12
Brenda Birdherd
212118
5200
2
800
0.1
Tim Turtletop
233255
688
1
即如果输入是2,代表是输入的是plus 用户,还需要提供透支金额,利率。
如果数组成员指向的是Brass对象,则调用Brass::ViewAcct(),如果指向的是BrassPlus对象,则调用BrassPlus::ViewAcct()。如果Brass::ViewAcct()没有被声明为虚的,那么在任何情况下都将调用Brass::ViewAcct()。
这个涉及到虚函数表,动态联编。下一节讨论这个主题。