上一个例子usebrass1.cpp中,方法是通过对象(而不是指针或者引用)来调用的,这个很清楚,也没有使用上虚函数的特性。本例子可以说明虚函数的使用场景和特点。
数组中所有元素的类型必须相同,而Brass 和BrassPlus是不同的类型。但是可以创建指向Brass的指针数组,这样每个元素的种类都相同,由于使用的是公有继承,指向Brass的指针也可以指向BrassPlus对象。
本例子的brass.h和brass.cpp 和usebrass1.cpp是一样的,这里就略过了。
usebrass2.cpp
- // Chapter13.3usebrass2.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
- //
-
- #include
- #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()。
这个涉及到虚函数表,动态联编。下一节讨论这个主题。