gpt4 book ai didi

详解C++基础——类继承中方法重载

转载 作者:qq735679552 更新时间:2022-09-28 22:32:09 26 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章详解C++基础——类继承中方法重载由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

1、前言 。

在上一篇C++基础博文中讨论了C++最基本的代码重用特性——类继承,派生类可以在继承基类元素的同时,添加新的成员和方法。但是没有考虑一种情况:派生类继承下来的方法的实现细节并不一定适合派生类的需求,此时派生类需要重载集成方法.

2、重载方法及虚函数 。

我们讨论《C++ Primer Plus》中的如下场景:银行记录客户信息,包括客户姓名、当前余额。客户这一类别当然能够创建客户对象、存款、取款以及显示信息。银行需要特殊记录具有透支权限的客户,因此这一类别的客户要额外记录透支上限、透支贷款利率以及当前透支总额。此外,取款和显示信息两个操作必须考虑客户的透支情况。综上,具有透支权限的客户是客户这一基类的派生类,派生类中不但需要添加新的成员,还要重载两个继承方法.

类声明代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#ifndef BRASS_H_
#define BRASS_H_
 
#include <string>
 
class Brass
{
private :
   std::string fullName;
   long acctNum;
   double balance;
public :
   Brass( const std::string& s = "Nullbody" , long an = -1, double ba = 0.0); //default constructor
   void Deposit( double amt);
   double Balance() const ;
   virtual void Withdraw( double amt); //virtual function
   virtual void ViewAcct() const ;
   virtual ~Brass() {} //使用虚析构函数确保先调用继承类析构函数
};
 
//brass plus account class
class BrassPlus: public Brass
{
private :
   double maxLoan;
   double rate;
   double owesBank;
public :
   BrassPlus( const std::string& s = "Nullbody" , long an = -1,
         double bal = 0.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 m) {maxLoan = m;} //inline function
   void ResetRate( double r) {rate = r;}
   void ResetOwes() {owesBank = 0;}
};
 
#endif
 
brass.h

类方法定义代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include"brass.h"
#include <iostream>
 
using std::cout;
using std::endl;
using std::string;
 
//brass methods
Brass::Brass( const string& s, long an, double bal)
{
   fullName = s;
   acctNum = an;
   balance = bal;
}
 
void Brass::Deposit( double amt)
{
   if (amt < 0)
     cout << "Negative deposit not allowed;"
       << "deposit is cancelled.\n" ;
   else
     balance += amt;
}
 
void Brass::Withdraw( double amt)
{
   if (amt < 0)
     cout << "Withdrawal amount must be positive;"
       << "withdrawal canceled.\n" ;
   else if (amt <= balance)
     balance -= amt;
   else
     cout << "Withdrawal amount of $" << amt
       << "exceeds your balance.\n"
       << "Withdrawal canceled.\n" ;
}
 
double Brass::Balance() const
{
   return balance;
}
 
void Brass::ViewAcct() const
{
   cout << "Client: " << fullName << endl;
   cout << "Account Number: " << acctNum << endl;
   cout << "Balance: $" << balance << endl;
}
 
//brassPlus methods
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;
}
 
//redefine viewacct()
void BrassPlus::ViewAcct() const
{
   Brass::ViewAcct();
   cout << "Maximum loan: $" << maxLoan << endl;
   cout << "Owed to bank: $" << owesBank << endl;
}
 
void BrassPlus::Withdraw( double amt)
{
   double bal = Balance();
   if (amt <= bal)
     Brass::Withdraw(amt);
   else if (amt <= bal + maxLoan - owesBank) // 已欠 + 此欠 ≤ maxLoan
   {
     double advance = amt - bal;
     owesBank += advance * (1.0+rate);
     cout << "Bank advance: $" << advance << endl;
     cout << "Finance charge: $" << advance*rate << endl;
     Deposit(advance);
     Brass::Withdraw(amt); // return to zero
   }
   else
     cout << "Credit limit exceeded. Transcation cancelled.\n" ;
}
 
brass.cpp

上述代码多了一个新的语法特性:虚函数(virtual function)。当基类声明中函数前加virtual,表示该函数为虚函数。区别在于当调用者是引用或者指针时,调用的是基类方法,还是派生类重载后的方法。具体区别我们后边在讨论。重中之重在于虚析构函数的意义。如果程序中使用delete删除占用的动态内存,且用于索引内存地址的指针类型是基类,那么即使该指针指向的是一个派生类对象,此时仅基类析构函数被调用。 我们着重观察brassPlus类重载的方法WithDraw有什么变化。这类客户由于具有透支权限,在取款时肯定要考虑欠款情况。若欲取出金额≤存储金额,则直接调用基类方法WithDraw,把存储金额减小;若欲取出金额大于存储金额,就必须进一步分析欠款情况。已欠款+此次欠款≤透支额度时,取款操作才有效。因此:owes+(amt - balance) ≤ maxLoan,进一步变形为:amt ≤ balance+maxLoan-owes.

3、应用程序示例及结果分析 。

现在看看应用程序代码和显示结果。APP代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include "brass.h"
 
int main()
{
   using std::cout;
   using std::endl;
 
   Brass Piggy( "Porcelot Pigg" ,381299,4000.00);
   BrassPlus Hoggy( "Horatio Hogg" ,382288,3000.00);
 
   Piggy.ViewAcct();
   cout << endl;
   Hoggy.ViewAcct();
   cout << endl;
  
   cout << "Depositing $1000 into the Hogg Account:\n" ;
   Hoggy.Deposit(1000.00);
   cout << "New balance: $" <<Hoggy.Balance() <<endl;
   cout << endl;
 
   cout << "Withdrawing $4200 from the Pigg Account:\n" ;
   Piggy.Withdraw(4200.00);
   cout << "Pigg account balance: $" << Piggy.Balance() << endl;
   cout << endl;
  
   cout << "Withdrawing $4200 from the Hogg Account:\n" ;
   Hoggy.Withdraw(4200.00);
   Hoggy.ViewAcct();
   cout << endl;
 
   Brass dom( "Dominic Banker" ,11224,4183.45);
   BrassPlus dot( "Dorothy Banker" ,12118,2592.00);
 
   Brass& b1_ref = dom;
   Brass& b2_ref = dot; //use BrassPlus::ViewAcct() function
 
   b1_ref.ViewAcct();
   cout << endl;
   b2_ref.ViewAcct();
   cout << endl;
 
   return 0;
}
 
usebrass.cpp

打印结果:

详解C++基础——类继承中方法重载

Pigg和Hogg分别是基类和派生类对象。当两种均取款额度超出存储金额时,Hogg由于具有透支权限,才得以成功完成操作。注意之后创建的两个对象dom和dot,从调用ViewAcct()函数过程中再次体会虚函数的意义。若没有使用virtual关键字,程序根据引用或指针的类型选择使用基类方法还是派生类同名的重载后方法。若使用该关键字,则根据引用或指针所指向对象的类型来选择。程序中,b1_ref和b2_ref均是Brass类引用,但分别是Brass类对象dom和BrassPlus类对象dot的别名,因此使用virtual关键字后的ViewAcct()函数,依次调用基类和派生类方法.

以上所述是小编给大家介绍的C++基础——类继承中方法重载详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我网站的支持! 。

最后此篇关于详解C++基础——类继承中方法重载的文章就讲到这里了,如果你想了解更多关于详解C++基础——类继承中方法重载的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com