多态公有继承(虚方法)

有的时候,派生类使用基类的方法的时候,是和基类使用这个方法的行为时不同的,换句话说,方法的行为取决于调用改方法的对象,这种行为叫做多态继承,通常有两种方法:

1:在派生类中重新定义基类的方法。

2:使用徐方法。

brass.h

#ifndef BRASS_H_
#define BRASS_H_
#include<string>

class Brass
{
private:
	std::string fullname;
	long acctNum;
	double balance;
public:
	Brass(const std::string &s="no name",long an=-1,double bal=0);
	void Deposit(double amt);
	virtual void Withdraw(double amt);				//虚方法,关键字virtual
	double Balance()const;
	virtual void ViewAcct()const;
	virtual ~Brass(){}
};

class BrassPlus:public Brass
{
private:
	double maxLoan;
	double rate;
	double owesBank;
public:
	BrassPlus(const std::string &s="no name",long an=-1,double bal=0,double ml=500,double r=0.11125);
	BrassPlus(const Brass &ba,double ml=500,double r=0.11125);
	virtual void ViewAcct()const;
	virtual void Withdraw(double amt);
	void ResetMax(double ma){maxLoan=ma;}
	void ResetRate(double r){rate=r;}
	void ResetOwes(){owesBank=0;}
};
#endif

从头文件中可以看出,派生类添加了3个私有数据成员和3个公有成员函数,另外,brass类在声明ViewAcct()  Withdraw()的时候使用了新的关键字virtual,这就是所谓的虚方法。

虚方法这种行为很方便,经常在基类中将派生类会重新定义的方法声明为虚方法。方法在基类中被声明为虚的后,它在派生类中将自动成为虚方法,然后就可以在派生类中进行重新定义。

下面重点讲一下他的调用:

1:使用成员限定符 . 就没有什么好说的了,那个调用他,就用那个定义的方法。例如dom.ViewAcct();

2:如果方法是通过引用或指针类型选择方法,则按照引用类型或者指针指向的类型在使用该种类型的方法,例如:

Brass dom("wang",11111,121);
BrassPlus dot("zhang",2222,112);
Brass &b1_ref=dom;
Brass &b2_ref=dot;
b1_ref.ViewAcct();
b2_ref.ViewAcct();
由于ViewAcct()是虚方法,这时候,b1_ref调用的是Brass::ViewAcct();  b2_ref调用的是BrassPlus::ViewAcct();因为,b1_ref引用的是Brass对象,而b2_ref引用的是BrassPlus对象。但是,如果ViewAcct不是虚方法,即基类定义他的时候没有用virtual关键字,那么,这个时候,b1_ref和 b2_ref都将调用的是Brass::ViewAcct(); 因为两个引用类型都是Brass.

brass.cpp

#include"brass.h"
#include<iostream>
using namespace std;

typedef std::ios_base::fmtflags format;
typedef std::streamsize precis;
format setFormat();
void restore(format f,precis p);

Brass::Brass(const string &s,long an,double bal)
{
	fullname=s;
	acctNum=an;
	balance=bal;
}

void Brass::Deposit(double amt)
{
	if(amt<0)
		cout<<"Negetive deposit not allowed;  deposit is cancelled."<<endl;
	else
		balance+=amt;
}

void Brass::Withdraw(double amt)
{
	format initialState=setFormat();
	precis prec=cout.precision(2);

	if(amt<0)
		cout<<"Withdrawal amount must be positive;  withdrawal canceled."<<endl;
	else if(amt<=balance)
		balance-=amt;
	else
		cout<<"Withdrawal amount if $"<<amt<<" exceeds your balance.\n"<<"Withfrawal canceled."<<endl;
	restore(initialState,prec);
}

double Brass::Balance()const
{
	return balance;
}

void Brass::ViewAcct()const
{
	format initialState=setFormat();
	precis prec=cout.precision(2);

	cout<<"Client: "<<fullname<<endl;
	cout<<"Account Number: "<<acctNum<<endl;
	cout<<"Balance: $"<<balance<<endl;
	restore(initialState,prec);
}

BrassPlus::BrassPlus(const string &s,long an,double bal,double ml,double r):Brass(s,an,bal)
{
	maxLoan=ml;
	owesBank=0.0;
	rate=r;
}

BrassPlus::BrassPlus(const Brass & ba,double ml,double r):Brass(ba)
{
	maxLoan=ml;
	owesBank=0.0;
	rate=r;
}

void BrassPlus::ViewAcct()const
{
	format initialState=setFormat();
	precis prec=cout.precision(2);

	Brass::ViewAcct();
	cout<<"Maximum loan: $"<<maxLoan<<endl;
	cout<<"Owed to bank: $"<<owesBank<<endl;
	cout.precision(3);
	cout<<"Loan Rate: "<<100*rate<<"%"<<endl;
	restore(initialState,prec);
}

void BrassPlus::Withdraw(double amt)
{
	format initialState=setFormat();
	precis prec=cout.precision(2);

	double bal=Balance();
	if(amt<=bal)
		Brass::Withdraw(amt);
	else if(amt<=bal+maxLoan-owesBank)
	{
		double advance=amt-bal;
		owesBank+=advance*(1.0+rate);
		cout<<"Bank advance: $"<<advance<<endl;
		cout<<"Finance charge: $"<<advance*rate<<endl;				//这时候  余额是4000
		
		Deposit(advance);											//这时候,余额就变成4200了,目的是为了使用Withdraw函数,使余额为0
		
		Brass::Withdraw(amt);										//这时候余额就变成0了
		
	}
	else
		cout<<"Credit limit exceeded.Transaction cancelled."<<endl;
	restore(initialState,prec);
}

format setFormat()
{
	return cout.setf(std::ios_base::fixed,std::ios_base::floatfield);
}

void restore(format f,precis p)
{
	cout.setf(f,std::ios_base::floatfield);
	cout.precision(p);
}
usebrass2.cpp

#include<iostream>
#include"brass.h"
#include<string>

const int CLUENTS=4;

int main()
{
	using namespace std;

	Brass * p_clients[CLUENTS];
	string temp;
	long tempnum;
	double tempbal;
	char kind;

	for(int i=0;i<CLUENTS;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<CLUENTS;i++)
	{
		p_clients[i]->ViewAcct();
		cout<<endl;
	}

	for(int i=0;i<CLUENTS;i++)
	{
		delete p_clients[i];
	}

	cout<<"Done."<<endl;

	system("pause");
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值