C++如何在派生类成员函数内调用基类的成员函数(包括构造函数)

C/C++常见问题 专栏收录该内容
10 篇文章 0 订阅

前段时间在实现一段代码的过程中遇到了几个相当简单却对于久疏C++战阵的人来说挺烦人的问题:

(而且在网上查了好久才在字里行间寻找到答案)

1.如何定义子类的构造函数,或者说如何在子类构造函数中调用父类的构造函数来实现对成员变量的初始化。

2.Const 成员函数的意义。

3.如何在派生类成员函数中调用基类的成员函数。

4.基类的私有成员是不能被派生类直接访问的,只有通过调用基类的公有方法(对私有成员修改的方法)才能实现

对基类私有成员的访问。

下面我们逐个解决前三个问题,并在解决完问题以后给出一个完整的例子:

1.如何在子类构造函数中调用基类的构造函数。

假设我有一个基类Account和一个派生类SavingAccount,SavingAccount除了继承了Account基类的一个balance变量外,自己也有一个interestrate变量。Account基类的构造函数如下:

Account::Account(double ba)
{
	balance = ba;
}
那么派生类调用基类构造方法来实现自己的构造方法并对成员进行初始化的定义为:

SavingAccount::SavingAccount(double ba, double inte) :Account(ba)
{
	// balance = ba;
	interestrate = inte;
}
利用基类的构造函数来实现对派生类从基类继承得到的成员变量的初始化,利用自己的构造函数来实现自身定义的

成员变量的初始化。

对于这个问题,可能有的人会产生一个疑问:如果我采用多文件结构(类声明放在.hpp文件中,类定义放在.cpp文件中),派生类的构造函数我该怎么声明呢?其实构造函数的声明是不用变的,例如上面SavingAccount派生类的构造函数声明依旧为:

SavingAccount(double ba, double ite);

到此第一个问题已经解决了,看下一问题:

2.Const 成员的意义

const 函数定义更多的是工程上的意义,对程序的效率本身影响不大,由于const成员调用const成员函数,所以说

在一些“一些成员函数修改对象,一下成员函数不修改对象”“非常量成员函数不能被常量成员对象调用,因为它可能企图修改常量的数据成员”诸如此类的问题,我们用const来解决,即对于不修改成员变量的方法我们用const标示一下。

3.如何在派生类成员函数中调用基类的成员函数

对于 非重名方法,直接调用即可,重名方法加 名词空间Account::credit()即可。

例如基类Account中的getBalance()方法,在派生类SavingAccount的方法calculate_Interest()调用方式为:

double SavingAccount::calculate_Interest()
{
	return (getBalance()*interestrate)/100.0;
}

直接调用了getBalance()。

三个问题已经解决完毕,接下来让我们来看一个比较完整的例子:

       创建一个银行账户的继承层次,表示银行的所有客户的账户,所有的客户都能在该银行的账户中存钱、取钱。账户也可以分成更为具体的类型,例如,存款账户SavingAccount依靠存款产生利息,支票账户CheckingAccount对每笔交易(存款或者取款)收取手续费。具体要求操作如下:

1. 创建一个类层次结构,Account为基类,派生类为SavingAccount(存款账户)CheckingAccount(支票账户)

2. 基类Account要求包括如下:表示账户余额的数据成员balance3个成员函数分别是向当前余额加钱的credit,从当前账户取钱的debit,查询当前账户余额的getBalance

3. 基类成员函数功能要求:除了完成基本功能(不再赘述)外,还需在取钱函数中实现如何保证账户不被透支,当所取金额大于账户金额时函数将保持balance不变,并给出“debit amount exceeded account balance”反馈。

4. 派生类SavingAccount要求:继承基类Account的功能,提供一个附加的数据成员interestrate返回账户的比率(利息百分比);构造函数接受初始余额值和初始利率值;另外提供一个public的成员函数calculate Interest,用来返回利息的数值,即balance 与 interestrate 的乘积。

5. 派生类CheckingAccount要求:继承基类Account 的功能,提供一个附加的数据成员表示每一笔交易的手续费用;构造函数接受初始余额值和交易费用值;重新定义成员函数credit 和 debit ,每笔交易完成后,从账户余额中减去交易的手续费用;重新定义这些函数时应使用基类的函数来更新账户余额;当debit函数成功被使用(即提款成功)才收取手续费用。(提示:定义Accountdebit函数时返回一个bool型值表示是否成功提取,用返回值判断是否收取手续费。当存款或者取款后的余额低于手续费则放弃本次交易并打印“Transaction fee exceeded account balance while debiting/crediting ”)

6. 严格按照要求定义上述成员变量和成员函数,所有成员变量定义为private

定义完成后编写主程序,能够生成不同的账户对象,调用成员函数完成相应的功能。

下面是 完整的实现程序:

//Account_ex.hpp 基类 派生类的 声明

/*
	Author By : Yumaosheng  
	Number :	21140211080
	Date: 20141109
*/
#include <iostream>
using namespace std;
//base class
class Account
{
private:
	double balance;
public:
	Account(double ba);
	~Account();
	int credit(double cash);
	int debit(double cash);
	double getBalance();
	int setBalance(double);	
};
//the sub class 
class SavingAccount : public Account
{
private:
	double interestrate;
public:
	SavingAccount(double ba, double ite);
	~SavingAccount();
	double calculate_Interest();
};
// the sub class of CheckingAccount
class CheckingAccount : public Account
{
private:
	double fee;
public:
	CheckingAccount(double ba,double fe);
	~CheckingAccount();
	int credit(double cash);
	int debit(double cash);
};

//Account_ex.cpp

//对基类 派生类的 声明

/*
	Author By : Yumaosheng  
	Number :	21140211080
	Date : 20141109
*/
#include <iostream>
#include "Account_ex.hpp"
using namespace std;

//the Implementation  of construction method
Account::Account(double ba)
{
	balance = ba;
}
//the Implementation  of deconstruction method
Account::~Account()
{
	balance = 0.0;
}
// the Implementation of credit method
// add some money to the Account
int Account::credit(double cash)
{
	// add the money to balance
	balance += cash;
	return 0;
}
// the Implementation of credit method
// get some money from the Account 
int Account::debit(double cash)
{
	//if get the more money than the balance
	if ((balance - cash) < 0.0)
	{
		cout<<"debit amount exceeded account balance"<<endl;
		return 1;
	}else
	{
		balance -= cash;
	}
	return 0;
}
// the Implementation of getBalance method
// return the balance
double Account::getBalance()
{
	return balance;
}
// the Implementation of setBalance() method
int Account::setBalance(double cash)
{
	balance = cash;

	return 0;
}
// the Implementation of SavingAccount 
// the Implementation of construction method of SavingAccount
//调用基类的构造函数
SavingAccount::SavingAccount(double ba, double inte) :Account(ba)
{
	// balance = ba;
	interestrate = inte;
}
// the Implementation of deconstruction method of SavingAccount
SavingAccount::~SavingAccount()
{
	// balance = 0.0;
	interestrate = 0.0;
}

double SavingAccount::calculate_Interest()
{
	//directly using the base's method getBalance()
	return (getBalance()*interestrate)/100.0;
}

// the Implementation of CheckingAccount
// the Implementation of construction method of CheckingAccount
// 调用基类的构造函数
CheckingAccount::CheckingAccount(double ba , double fe) : Account(ba)
{
	// balance = ba;
	// cout<<getBalance()<<endl; //test the construction 
	fee = fe;
}
CheckingAccount::~CheckingAccount()
{
//	this->balance = 0.0;
	fee = 0.0;
}
// the  Implementation of CheckingAccount's credit 
int CheckingAccount::credit(double cash)
{
	if (!Account::credit(cash))
	{
		if (getBalance() > fee)
		{
			// balance -= fee;
			Account::debit(fee);
		}else
		{
			// balance -= cash;
			Account::debit(cash);
			cout<<"Transaction fee exceeded account balance while crediting"<<endl;
		}
	}
	return 0;
}
// the Implementation of CheckingAccount's debit
int CheckingAccount::debit(double cash)
{
	if (! Account::debit(cash))
	{
		if (Account::getBalance() > fee)
		{
			// balance -= fee;
			Account::debit(fee);
		}else
		{
			// balance +=cash;
			Account::credit(cash);
			cout<<"Transaction fee exceeded account balance while debiting"<<endl;
		}
	}
	return 0;
}

下面是Main()函数,对上述类定义进行测试:

/*
	Author By : Yumaosheng  
	Number :	21140211080
	Date: 20141109
*/
#include "Account_ex.hpp"
#include <iostream>

int main(int argc, char const *argv[])
{
	//generate a SavingAccount object
	SavingAccount saving( 100, 3 );
	// double money = saving.calculate_Interest();
	// cout<<money<<endl;
	CheckingAccount checking1( 100, 5 );
	CheckingAccount checking2( 50, 5 );
	// test the SavingAccount
	cout<<"SavingAccount:"<<endl;
	// debit 200 yuan
	saving.debit(200);
	// debit 40 yuan
	saving.debit(40);
	// credit 50 yuan
	saving.credit(50);
	// debit 49 yuan
	saving.debit(49);
	// debit 43 yuan
	saving.debit(43);
	// credit 1 yuan
	saving.credit(1);
	
	saving.setBalance(saving.calculate_Interest()+saving.getBalance());
	
	cout<<saving.getBalance()<<endl;

	// test the CheckingAccount
	cout <<"Checking Account1:"<< endl;
	// debit 200
	checking1.debit(200);
	// debit 40
	checking1.debit(40);
	// credit 50
	checking1.credit(50);
	// debit 49
	checking1.debit(49);
	// debit 43
	checking1.debit(43);
	// credit 1
	checking1.credit(1);
	
	cout<<checking1.getBalance()<<endl;
	
	// test the checking2
	cout <<"Checking Account2:"<< endl;
	// debit 200
	checking2.debit(200);
	// debit 40
	checking2.debit(40);
	// credit 50
	checking2.credit(50);
	// debit 49
	checking2.debit(49);
	// debit 43
	checking2.debit(43);
	// credit 1
	checking2.credit(1);
	
	cout<<checking2.getBalance()<<endl;
	
	return 0;
}

上述就是完整的例子。




©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

茂升快跑

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值