C++ Primer Plus学习:第十三章 类继承(3)

抽象基类
  eg

    acctABC.h

#ifndef ACCTABC_H_
#define ACCTABC_H_

//Abstract Base Class
class AcctABC
{
      private:
              enum{MAX = 35};
              char fullName[MAX];
              long acctNum;
              double balance;
      protected:
                const char *FullName()const{return fullName;}
                long AcctNum()const{return acctNum;}
                std::ios_base::fmtflags SetFormat()const;
      public:
             AcctABC(const char *s = "Nullbody",long an = -1,double bal = 0.0);
             void Deposit(double amt);
             //pure virtual function
             virtual void Withdraw(double amt) = 0;
             double Balance()const{return balance;};
             //pure virtual function
             virtual void ViewAcct()const = 0;
             virtual ~AcctABC(){}
      };
      
//Brass Account Class
class Brass:public AcctABC
{
      public:
             Brass(const char *s = "Nullbody",long an = -1,double bal = 0.0):AcctABC(s,an,bal){}
             virtual void Withdraw(double amt);
             virtual void ViewAcct()const;
             virtual ~Brass(){}
      };
      
//Brass Plus Account Class
class BrassPlus:public AcctABC
{
      private:
              double maxLoan;
              double rate;
              double owesBank;
      public:
             BrassPlus(const char *s = "Nullbody",long an = -1,double bal = 0.0,double ml = 500,double r = 0.10);
             BrassPlus(const Brass & ba,double ml = 500,double r = 0.1);
             virtual void ViewAcct()const;
             virtual void Withdraw(double amt);
             void ResetMax(double m){maxLoan = m;}
             void ResetRate(double r){rate = r;}
             void ResetOwes(){owesBank = 0;}
      };
      
#endif


    acctABC.cpp

#include <iostream>
#include <cstring>
#include "acctabc.h"
using std::cout;
using std::endl;
using std::ios_base;

AcctABC::AcctABC(const char *s,long an,double bal)
{
                       std::strncpy(fullName,s,MAX-1);
                       fullName[MAX-1] = '\0';
                       acctNum = an;
                       balance = bal;
                       }
                       
void AcctABC::Deposit(double amt)
{
     if(amt < 0)
            cout<<"Negative deposit not allowed;deposit is cancelled.\n";
     else
         balance += amt;
     }
     
void AcctABC::Withdraw(double amt)
{
     balance -= amt;
     }
     
//protected method
ios_base::fmtflags AcctABC::SetFormat()const
{
                   ios_base::fmtflags initialState = cout.setf(ios_base::fixed,ios_base::floatfield);
                   cout.setf(ios_base::showpoint);
                   cout.precision(2);
                   return initialState;
                   }
                   
//Brass methods
void Brass::Withdraw(double amt)
{
     if(amt < 0)
            cout<<"Withdrawal amount must be positive;withdrawal canceled.\n";
     else if(amt <= Balance())
          AcctABC::Withdraw(amt);
     else
         cout<<"Withdrawal amount of {1}quot;<<amt<<" exceeds your balance.\nWithdrawal canceled.\n";
     }
     
void Brass::ViewAcct()const
{
     ios_base::fmtflags initialState = SetFormat();
     cout<<"Brass Client: "<<FullName()<<endl;
     cout<<"Account Number: "<<AcctNum()<<endl;
     cout<<"Balance:$ "<<Balance()<<endl;
     cout.setf(initialState);
     }
     
//BrassPlus method
BrassPlus::BrassPlus(const char *s,long an,double bal,double ml,double r):AcctABC(s,an,bal)
{
                           maxLoan = ml;
                           owesBank = 0.0;
                           rate = r; 
                           }
                           
BrassPlus::BrassPlus(const Brass &ba,double ml,double r):AcctABC(ba)
{
                           maxLoan = ml;
                           owesBank = 0.0;
                           rate = r; 
                           }
                           
void BrassPlus::ViewAcct()const
{
     ios_base::fmtflags initialState = SetFormat();
     cout<<"BrassPlus Client: "<<FullName()<<endl;
     cout<<"Account Number: "<<AcctNum()<<endl;
     cout<<"Balance:{1}quot;<<Balance()<<endl;
     cout<<"Maximum loan:{1}quot;<<maxLoan<<endl;
     cout<<"Owed to bank:{1}quot;<<owesBank<<endl;
     cout<<"Loan Rate: "<<100*rate<<"%\n";
     cout.setf(initialState);
     }
     
void BrassPlus::Withdraw(double amt)
{
     ios_base::fmtflags initialState = SetFormat();
     
     double bal = Balance();
     if(amt <= bal)
            AcctABC::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;
          Deposit(advance);
          AcctABC::Withdraw(amt);
          }
     else
         cout<<"Credit limit exceeded.Transaction cancelled.\n";
     cout.setf(initialState);
     }


    usebrass3.cpp

#include <iostream>
#include "acctabc.h"

const int CLIENTS = 4;
const int LEN = 40;

int main()
{
    using std::cin;
    using std::cout;
    using std::endl;
    
    //指针表达Brass与BrassPlus 
    AcctABC * p_clients[CLIENTS];
    
    int i;
    for(i = 0;i<CLIENTS;i++)
    {
          char temp[LEN];
          long tempnum;
          double tempbal;
          char kind;
          cout<<"Enter client's name:";
          cin.getline(temp,LEN);
          cout<<"Enter client's account number:";
          cin>>tempnum;
          cout<<"Enter opening balance:{1}quot;;
          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构造Brass类对象 
                  p_clients[i] = new Brass(temp,tempnum,tempbal);
          else
          {
              double tmax,trate;
              cout<<"Enter the interest rate as a decimal fraction: ";
              cin>>trate;
              //p_client构造BrassPlus类对象 
              p_clients[i] = new BrassPlus(temp,tempnum,tempbal,tmax,trate);
              }
          while(cin.get()!='\n')
                                continue;
          }
    cout<<endl;
    for(i=0;i<CLIENTS;i++)
    {
                          p_clients[i]->ViewAcct();
                          cout<<endl;
                          }
                          
    for(i = 0;i<CLIENTS;i++)
    {
          delete p_clients[i];
          }
    cout<<"Done!\n";
    
    system("pause");
    return 0;
    }


继承和动态内存分配
  当基类和派生类都采用动态内存分配时,派生类的析造函数、复制构造函数及赋值操作符都必须使用相应的基类方法来处理基类元素
    析构函数是自动完成
    构造函数是通过初始化成员列表中基类的复制构造函数来完成
    赋值操作符,通过使用作用域解析操作符显示地调用基类的赋值操作符
  eg

    dma.h

#ifndef DMA_H_
#define DMA_H_
#include <iostream>

//class base
class baseDMA
{
      private:
              char *label;
              int rating;
      public:
             baseDMA(const char *l="null",int r = 0);
             baseDMA(const baseDMA &rs);
             virtual ~baseDMA();
             baseDMA & operator = (const baseDMA & rs);
             friend std::ostream & operator<<(std::ostream & os,const baseDMA & rs);
      };
      
//derived class
class lacksDMA:public baseDMA
{
      private:
              enum{COL_LEN = 40};
              char color[COL_LEN];
      public:
             lacksDMA(const char *c = "blank",const char *l = "null",int r= 0);
             lacksDMA(const char *c,const baseDMA & rs);
             friend std::ostream & operator<< (std::ostream & os,const lacksDMA & rs);
             
      };
      
//derived class
class hasDMA:public baseDMA
{
      private:
              char * style;
      public:
             hasDMA(const char *s = "none",const char *l = "null",int r = 0);
             hasDMA(const char *s,const baseDMA & rs);
             hasDMA(const hasDMA & hs);
             ~hasDMA();
             hasDMA & operator=(const hasDMA & rs);
             friend std::ostream & operator<<(std::ostream & os,const hasDMA & rs);
      };
      
#endif


    dma.cpp

#include "dma.h"
#include <cstring>

//baseDMA method
baseDMA::baseDMA(const char * l,int r)
{
                       label = new char[std::strlen(l)+1];
                       std::strcpy(label,l);
                       rating = r;
                       }
                       
baseDMA::baseDMA(const baseDMA & rs)
{
                       label = new char[std::strlen(rs.label)+1];
                       std::strcpy(label,rs.label);
                       rating = rs.rating;
                       }
                       
baseDMA::~baseDMA()
{
                   delete []label;
                   }
                   
baseDMA & baseDMA::operator=(const baseDMA & rs)
{
        if(this == &rs)
                return *this;
        delete []label;
        label = new char[std::strlen(rs.label)+1];
        std::strcpy(label,rs.label);
        rating = rs.rating;
        return *this;
        }
        
std::ostream & operator<<(std::ostream & os,const baseDMA & rs)
{
             os<<"Label: "<<rs.label<<std::endl;
             os<<"Rating: "<<rs.rating<<std::endl;
             return os;
             }
             
//lacksDMA method
lacksDMA::lacksDMA(const char *c,const char *l,int r):baseDMA(l,r)
{
                         std::strncpy(color,c,39);
                         color[39] = '\0';
                         }
                         
lacksDMA::lacksDMA(const char *c,const baseDMA & rs):baseDMA(rs)
{
                         std::strncpy(color,c,COL_LEN-1);
                         color[COL_LEN-1] = '\0';
                         }
                         
std::ostream & operator<<(std::ostream & os,const lacksDMA & ls)
{
             os<<(const baseDMA & )ls;
             os<<"Color: "<<ls.color<<std::endl;
             return os;
             }
             
//hasDMA method
hasDMA::hasDMA(const char *s,const char *l,int r ):baseDMA(l,r)
{
                     style = new char[std::strlen(s)+1];
                     std::strcpy(style,s);
                     }

hasDMA::hasDMA(const char *s,const baseDMA &rs):baseDMA(rs)
{
                     style = new char[std::strlen(s)+1];
                     std::strcpy(style,s);
                     }
                     
hasDMA::hasDMA(const hasDMA & hs):baseDMA(hs)
{
                     style = new char[std::strlen(hs.style)+1];
                     std::strcpy(style,hs.style);
                     }
                     
hasDMA::~hasDMA()
{
                 delete []style;
                 }
                 
hasDMA & hasDMA::operator=(const hasDMA & hs)
{
       if(this == &hs)
               return *this;
       baseDMA::operator=(hs);//copy base protion
       style = new char[std::strlen(hs.style)+1];
       std::strcpy(style,hs.style);
       return *this;
       }

std::ostream & operator<<(std::ostream & os,const hasDMA & hs)
{
             os<<(const baseDMA & )hs;
             os<<"Style: "<<hs.style<<std::endl;
             return os;
             }


    usedma.cpp

#include <iostream>
#include "dma.h"

int main()
{
    using std::cout;
    using std::endl;
    
    baseDMA shirt("Protabelly",8);
    lacksDMA balloon("red","Blimpo",4);
    hasDMA map("Mercator","Buffalo Keys",5);
    cout<<shirt<<endl;
    cout<<balloon<<endl;
    cout<<map<<endl;
    lacksDMA balloon2(balloon);
    hasDMA map2;
    map2 = map;
    cout<<balloon2<<endl;
    cout<<map2<<endl;
    
    system("pause");
    return 0;
    }


成员函数属性


  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值