第十三章类和继承:多态共有继承04
虚方法的行为
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
例如: 虚方法的行为
提示:以下是本篇文章正文内容,下面案例可供参考
三、3.演示虚方法的行为
在程序清单13.9中,方法是通过对象(而不是指针或引用)调用的,没有使用虚方法特性。下面来看一个使用了虚方法的例子。假设要同时管理Brass和 BrassPlus 账户,如果能使用同一个数组来保存 Brsss和 BrassPlus对象,将很有帮助,但这是不可能的。数组中所有元素的类型必须相同,而Brass 和 BrassPlus是不同的类型。然而,可以创建指向 Brass的指针数组。这样,每个元素的类型都相同,但由于使用的是公有继承模型,因此 Brass指针既可以指向 Brass对象,也可以指向 BrassPlus 对象。因此,可以使用一个数组来表示多种类型的对象。这就是多态性,程序清单13.10是一个简单的例子。
二、使用步骤
1.引入库
代码如下(示例):
// usebrass2.cpp -- polymorphic example
// compile with brass.cpp
#include <iostream>
#include <string>
#include "brass.h"
const int CLIENTS = 4;
int main()
{
using std::cin;
using std::cout;
using std::endl;
Brass * p_clients[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_clients[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_clients[i] = new BrassPlus(temp, tempnum, tempbal,
tmax, trate);
}
while (cin.get() != '\n')
continue;
}
cout << endl;
for (int i = 0; i < CLIENTS; i++)
{
p_clients[i]->ViewAcct();
cout << endl;
}
for (int i = 0; i < CLIENTS; i++)
{
delete p_clients[i]; // free memory
}
cout << "Done.\n";
/* code to keep window open
if (!cin)
cin.clear();
while (cin.get() != '\n')
continue;
*/
return 0;
}
程序清单 13.10根据用户的输入来确定要添加的账户类型,然后使用 new 创建并初始化相应类型的对象。您可能还记得,getline(cin,temp)从 cin 读取一行输入,并将其存储到string 对象 temp 中。下面是该程序的运行情况:

总结
提示:这里对文章进行总结:
多态性是由下述代码提供的:
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 必须有一个虚析构函数,即使该析构函数不执行任何操作。
646

被折叠的 条评论
为什么被折叠?



