国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

詳解C++基礎――類繼承中方法重載

2020-01-26 13:28:32
字體:
來源:轉載
供稿:網友

一、前言

在上一篇C++基礎博文中討論了C++最基本的代碼重用特性――類繼承,派生類可以在繼承基類元素的同時,添加新的成員和方法。但是沒有考慮一種情況:派生類繼承下來的方法的實現細節并不一定適合派生類的需求,此時派生類需要重載集成方法。

二、重載方法及虛函數

我們討論《C++ Primer Plus》中的如下場景:銀行記錄客戶信息,包括客戶姓名、當前余額。客戶這一類別當然能夠創建客戶對象、存款、取款以及顯示信息。銀行需要特殊記錄具有透支權限的客戶,因此這一類別的客戶要額外記錄透支上限、透支貸款利率以及當前透支總額。此外,取款和顯示信息兩個操作必須考慮客戶的透支情況。綜上,具有透支權限的客戶是客戶這一基類的派生類,派生類中不但需要添加新的成員,還要重載兩個繼承方法。

類聲明代碼:

#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 classclass 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;}};#endifbrass.h

類方法定義代碼:

#include"brass.h"#include <iostream>using std::cout;using std::endl;using std::string;//brass methodsBrass::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 methodsBrassPlus::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。

三、應用程序示例及結果分析

現在看看應用程序代碼和顯示結果。APP代碼:

#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

打印結果:

Pigg和Hogg分別是基類和派生類對象。當兩種均取款額度超出存儲金額時,Hogg由于具有透支權限,才得以成功完成操作。注意之后創建的兩個對象dom和dot,從調用ViewAcct()函數過程中再次體會虛函數的意義。若沒有使用virtual關鍵字,程序根據引用或指針的類型選擇使用基類方法還是派生類同名的重載后方法。若使用該關鍵字,則根據引用或指針所指向對象的類型來選擇。程序中,b1_ref和b2_ref均是Brass類引用,但分別是Brass類對象dom和BrassPlus類對象dot的別名,因此使用virtual關鍵字后的ViewAcct()函數,依次調用基類和派生類方法。

以上所述是小編給大家介紹的C++基礎――類繼承中方法重載詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 崇文区| 颍上县| 元阳县| 临清市| 靖安县| 益阳市| 沁阳市| 壤塘县| 马尔康县| 湖口县| 大兴区| 绥江县| 嘉祥县| 山阴县| 咸宁市| 阿拉善左旗| 南江县| 民和| 宝应县| 固原市| 呈贡县| 宜兰县| 德钦县| 鹿邑县| 贵定县| 西乌| 嘉义市| 尼木县| 龙胜| 嘉黎县| 二手房| 丁青县| 光山县| 龙州县| 浙江省| 盐津县| 房产| 雅安市| 尼木县| 兰溪市| 措美县|