C++ Primer Plus学习:第十三章 类继承(3)
来源:互联网 发布:淘宝兼职外宣说说内容 编辑:程序博客网 时间:2024/05/18 01:12
抽象基类
eg
当基类和派生类都采用动态内存分配时,派生类的析造函数、复制构造函数及赋值操作符都必须使用相应的基类方法来处理基类元素
析构函数是自动完成
构造函数是通过初始化成员列表中基类的复制构造函数来完成
赋值操作符,通过使用作用域解析操作符显示地调用基类的赋值操作符
eg
eg
acctABC.h
#ifndef ACCTABC_H_#define ACCTABC_H_//Abstract Base Classclass 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 Classclass 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 Classclass 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 methodios_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 methodsvoid 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 methodBrassPlus::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 baseclass 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 classclass 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 classclass 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 methodbaseDMA::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 methodlacksDMA::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 methodhasDMA::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; }
成员函数属性
- C++ Primer Plus学习:第十三章 类继承(3)
- C++ Primer Plus学习:第十三章 类继承(1)
- C++ Primer Plus学习:第十三章 类继承(2)
- 2012/1/31 《C++ Primer Plus》第十三章:类继承 学习笔记
- 《C++ Primer Plus(第六版)》(25)(第十三章 类继承 笔记)
- 《C++ Primer Plus(第六版)》(26)(第十三章 类继承 复习题答案)
- 《C++ Primer Plus(第六版)》(27)(第十三章 类继承 编程题答案)
- 【学习C++】C++ Primer Plus (第六版)第十三章编程练习1-4
- c++primer plus第十三章-派生类与基类
- C++Primer Plus(第六版) 第十三章 第一题
- C++Primer Plus(第六版) 第十三章 第二题
- C++Primer Plus(第六版) 第十三章 第四题
- 【学习笔记】C++primer plus 13.继承
- 继承和动态内存分配(C++ Primer Plus 第十三章)
- 继承和动态内存分配(C++ Primer Plus 第十三章)
- c++primer plus第十四章-多重继承、模板类
- 类多继承及包含练习(c++primer plus)
- C Primer Plus 第十三章 学习总结……2015.5.8
- hdu 1862 EXCEL排序
- 网站与网络蜘蛛
- 在SQL中创建用户自定义拼音函数
- sudo apt-get 和dpkg命令大全
- 2.1例题 鸡兔同笼
- C++ Primer Plus学习:第十三章 类继承(3)
- struts2 <s:iterator/>怎样取得循环的索引?
- delphi 中本年,本月,本周第一天和最后一天
- 指南针+图片定位
- jdk与openjdk
- 使用vim/sed去除网上copy的源代码行号和空格
- vb.net 判断目录或文件的存在方法
- IT企业新员工应该具有的基本素养
- winform打开一个新程序