文章目录
13.1 2 3
代码
#pragma once
#ifndef TABTENN0_H_
#define TABTENN0_H_
#include <string>
using namespace std;
class TableTennisPlayer
{
private:
string firstname;
string lastname;
bool hasTable;
public:
TableTennisPlayer(const string & fn = "none",
const string & ln = "none", bool ht = false);
void Name() const;
bool HasTable() const { return hasTable; };
void ResetTable(bool v){hasTable = v; };
};
#endif // !TABTENN0_H_
#include <iostream>
#include "tabtenn0.h"
TableTennisPlayer::TableTennisPlayer(const string & fn,
const string & ln, bool ht):firstname(fn),
lastname(ln), hasTable(ht) {}
void TableTennisPlayer::Name()const
{
std::cout << lastname << ", " << firstname;
}
#include <iostream>
#include "tabtenn0.h"
using namespace std;
int main()
{
//用C风格字符串实例化对象
TableTennisPlayer player1("Chuck", "Blizzard", true);
TableTennisPlayer player2("Tara", "Boomdea", false);
player1.Name();
if (player1.HasTable())
cout << ": has a table.\n";
else
cout << ": has not a table.\n";
player2.Name();
if (player2.HasTable())
cout << ": has a table.\n";
else
cout << ": has not a table.\n";
system("pause");
return 0;
}
结果
知识点
1.用C风格字符串实例化对象
13.4 5 6
代码
#pragma once
#ifndef TABTENN1_H_
#define TABTENN1_H_
#include <string>
using namespace std;
class TableTennisPlayer
{
private:
string firstname;
string lastname;
bool hasTable;
public:
TableTennisPlayer(const string & fn = "none",
const string & ln = "none", bool ht = false);
void Name() const;
bool HasTable() const { return hasTable; };
void ResetTable(bool v) { hasTable = v; };
};
//派生类声明格式 class 派生类名称 :public 基类
//派生类解决代码重复的问题
//派生类对象存储了基类的数据成员,可是使用基类的方法
class RatedPlayer :public TableTennisPlayer
{
private:
unsigned int rating;
public:
RatedPlayer(unsigned int r = 0, const string & fn = "none",
const string & ln = "none", bool ht = false);
//派生类的构造函数:
//派生类不能直接访问基类的私有成员,必须通过基类方法进行访问
RatedPlayer(unsigned int r, const TableTennisPlayer & tp);
unsigned int Rating() const { return rating; }
void ResetRating(unsigned int r) { rating = r; }
};
#endif // !TABTENN1_H_
#include <iostream>
#include "tabtenn1.h"
TableTennisPlayer::TableTennisPlayer(const string & fn,
const string & ln, bool ht):firstname(fn),
lastname(ln),hasTable(ht) {}
void TableTennisPlayer::Name() const
{
std::cout << lastname << ", " << firstname;
}
RatedPlayer::RatedPlayer(unsigned int r, const string & fn,
const string & ln, bool ht) :TableTennisPlayer(fn, ln, ht)
{
rating = r;
}
RatedPlayer::RatedPlayer(unsigned int r, const TableTennisPlayer & tp)
: TableTennisPlayer(tp), rating(r)
{
}
#include <iostream>
#include "tabtenn1.h"
using namespace std;
int main()
{
//创建TableTennisPlayer对象 player1
TableTennisPlayer player1("Tara", "Boomdea", false);
//创建RatedPlayer对象rplayer1
RatedPlayer rplayer1(1140, "Mallory", "Duck", true);
//派生类对象调用基类方法
rplayer1.Name();
if (rplayer1.HasTable())
cout << ": has a table.\n";
else
cout << ": has not a table.\n";
//基类调用自己的方法
player1.Name();
if (player1.HasTable())
cout << ": has a table";
else
cout << ": has not a table.\n";
cout << "Name: ";
rplayer1.Name();
cout << "; Rating: " << rplayer1.Rating() << endl;
//创建RatedPlayer对象rplayer2
RatedPlayer rplayer2(1212, player1);
cout << "Name: ";
rplayer2.Name();
cout << "; Rating: " << rplayer2.Rating() << endl;
system("pause");
return 0;
}
结果
知识点
1.派生类声明形式
2.派生类构造函数
3.派生类创造对象
4.派生类调用基类方法
13.7 8 9
代码
#pragma once
#ifndef BRASS_H_
#define BRASS_H_
#include <string>
using namespace std;
class Brass
{
private:
string fullName;
long acctNum;
double balance;
public:
Brass(const string & s = "Nullbody", long an = -1,
double bal = 0.0);
void Deposit(double amt);
double Balance() const;
//虚方法
virtual void Withdraw(double amt);
virtual void ViewAcct() const;
//虚析构函数
virtual ~Brass(){}
};
class BrassPlus :public Brass
{
//添加3个私有数据成员
private:
double maxLoan;
double rate;
double owesBank;
public:
BrassPlus(const string & s = "Nullbody", long an = -1,
double bal = 0.0, double ml = 500,
double r = 0.11125);
BrassPlus(const Brass & ba, double m1 = 500,
double r = 0.11125);
virtual void ViewAcct()const;
virtual void Withdraw(double amt);
//添加3个共有成员函数
void ResetMax(double m) { maxLoan = m; }
void ResetRate(double r) { rate = r; };
void ResetOwes() { owesBank = 0; }
};
#endif // !BRASS_H_
#include <iostream>
#include "brass.h"
using namespace std;
//typedef 取别名
typedef ios_base::fmtflags format;
typedef streamsize precis;
format setFormat();
void restore(format f, precis p);
//定义基类构造函数
Brass::Brass(const string & s, long an, double bal)
{
fullName = s;
acctNum = an;
balance = bal;
}
//定义基类方法Deposit
void Brass::Deposit(double amt)
{
if (amt < 0)
cout << "Negative deposit not allowed; "
<< "deposit is cancelled.\n";
else
balance += amt;
}
//定义基类方法Withdraw
void Brass::Withdraw(double amt)
{
format initialState = setFormat();
precis prec = cout.precision(2);
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";
restore(initialState, prec);
}
//定义基类方法Balance
double Brass::Balance() const
{
return balance;
}
//定义基类方法ViewAcct
void Brass::ViewAcct() const
{
format initialState = setFormat();
precis prec = cout.precision(2);
cout << "Client: " << fullName << endl;
cout << "Account Number: " << acctNum << endl;
cout << "Balance: $" << balance << endl;
restore(initialState, prec);
}
//定义派生类构造函数
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;
}
//定义派生类方法ViewAcct
void BrassPlus::ViewAcct() const
{
format initialState = setFormat();
precis prec = cout.precision(2);
Brass::ViewAcct();
cout << "Maximum loan: $" << maxLoan << endl;
cout << "Owed to bank: $" << owesBank << endl;
cout.precision(3);
cout << "Loan Rate: " << 100 * rate << "%\n";
restore(initialState, prec);
}
//定义派生类方法Withdraw
void BrassPlus::Withdraw(double amt)
{
format initialState = setFormat();
precis prec = cout.precision(2);
double bal = Balance();
if (amt <= bal)
Brass::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);
Brass::Withdraw(amt);
}
else
cout << "Credit limit exceeded. Transaction cancelled.\n";
restore(initialState, prec);
}
format setFormat()
{
return cout.setf(ios_base::fixed,
ios_base::floatfield);
}
void restore(format f, precis p)
{
cout.setf(f, ios_base::floatfield);
cout.precision(p);
}
#include <iostream>
#include "brass.h"
using namespace std;
int main()
{
//创建Brass类对象Piggy
Brass Piggy("Porcelot Pigg", 381299, 4000.00);
//创建BrassPlus类对象Piggy
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 << "Withdrawing $4200 from the Hogg Account:\n";
Hoggy.Withdraw(4200.00);
Hoggy.ViewAcct();
system("pause");
return 0;
}
结果
知识点
1.virtual关键字:虚方法
13.10
代码
#include <iostream>
#include <string>
#include "brass.h"
using namespace std;
const int CLIENTS = 4;
int main()
{
//创建一个指向Brass类对象的指针数组
Brass * p_clients[CLIENTS];
string temp;
long tempnum;
double tempbal;
char kind;
for (int i = 0; i < CLIENTS; i++)
{
cout << "Enter client's name: ";
getline(cin, temp);
cout << "Enter client's account number: ";
cin >> tempnum;
cout << "Enter opening balance: $";
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[i] = new Brass(temp, tempnum, tempbal);
else
{
double tmax, trate;
cout << "Enter the overdraft limit: $";
cin >> tmax;
cout << "Enter the interest rate "
<< "as a decimal fraction: ";
cin >> trate;
p_clients[i] = new BrassPlus(temp, tempnum, tempbal,
tmax, trate);
}
while(cin.get() != '\n')
continue;
}
cout << endl;
for (int i = 0; i < CLIENTS; i++)
{
p_clients[i]->ViewAcct();
cout << endl;
}
for (int i = 0; i < CLIENTS; i++)
{
delete p_clients[i];
}
cout << "Done.\n";
system("pause");
return 0;
}
结果
知识点
1.多态
13.11 12 13
代码
//抽象基类
#pragma once
#ifndef ACCTABC_H_
#define ACCTABC_H_
#include <iostream>
#include<string>
using namespace std;
class AcctABC
{
private:
string fullName;
long acctNum;
double balance;
protected:
struct Formatting
{
ios_base::fmtflags flag;
streamsize pr;
};
const string & FullName() const { return fullName; }
long AcctNum() const { return acctNum; }
Formatting SetFormat() const;
void Restore(Formatting & f)const;
public:
AcctABC(const string & s = "Nullbody", long an = -1,
double bal = 0.0);
void Deposit(double amt);
virtual void Withdraw(double amt) = 0;
double Balance() const { return balance; };
virtual void ViewAcct() const = 0;
~AcctABC(){}
};
class Brass :public AcctABC
{
public:
Brass(const string & s = "Nullbody", long an = -1,
double bal = 0.0):AcctABC(s, an, bal){ }
virtual void Withdraw(double amt);
virtual void ViewAcct() const;
virtual ~Brass() {}
};
class BrassPlus :public AcctABC
{
private:
double maxLoan;
double rate;
double owesBank;
public:
BrassPlus(const string & 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_H_
#include <iostream>
#include "acctabc.h"
using namespace std;
AcctABC::AcctABC(const string & s, long an, double bal)
{
fullName = s;
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;
}
AcctABC::Formatting AcctABC::SetFormat() const
{
Formatting f;
f.flag = cout.setf(ios_base::fixed, ios_base::floatfield);
f.pr = cout.precision(2);
return f;
}
void AcctABC::Restore(Formatting & f) const
{
cout.setf(f.flag, ios_base::floatfield);
cout.precision(f.pr);
}
void Brass::Withdraw(double amt)
{
if (amt < 0)
cout << "Withdawal amount must be positive;"
<< "withdrawal canceled.\n";
else if (amt <= Balance())
AcctABC::Withdraw(amt);
else
cout << "Withdrawal amount of $" << amt
<< " exceeds your balance.\n"
<< "Withdrawal canceled.\n";
}
void Brass::ViewAcct() const
{
Formatting f = SetFormat();
cout << "Brass Client: " << FullName() << endl;
cout << "Account Number: " << AcctNum() << endl;
cout << "Balance: $" << Balance() << endl;
Restore(f);
}
BrassPlus::BrassPlus(const string & 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
{
Formatting f = SetFormat();
cout << "BrassPlus Client: " << FullName() << endl;
cout << "Account Number: " << AcctNum() << endl;
cout << "Balance: $" << Balance() << endl;
cout << "Maximum loan: $" << maxLoan << endl;
cout << "Owed to bank: $" << owesBank << endl;
cout.precision(3);
cout << "Loan Rate: " << 100 * rate << "%\n";
Restore(f);
}
void BrassPlus::Withdraw(double amt)
{
Formatting f = 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";
Restore(f);
}
#include <iostream>
#include <string>
#include "acctabc.h"
using namespace std;
const int CLIENTS = 4;
int main()
{
Brass * p_clients[CLIENTS];
string temp;
long tempnum;
double tempbal;
char kind;
for (int i = 0; i < CLIENTS; i++)
{
cout << "Enter client's name: ";
getline(cin, temp);
cout << "Enter client's account number: ";
cin >> tempnum;
cout << "Enter opening balance: $";
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[i] = new Brass(temp, tempnum, tempbal);
else
{
double tmax, trate;
cout << "Enter the overdraft limit: $";
cin >> tmax;
cout << "Enter the interest rate "
<< "as a decimal fraction: ";
cin >> trate;
p_clients[i] = new BrassPlus(temp, tempnum, tempbal,
tmax, trate);
}
while(cin.get() != '\n')
continue;
}
cout << endl;
for (int i = 0; i < CLIENTS; i++)
{
p_clients[i]->ViewAcct();
cout << endl;
}
for (int i = 0; i < CLIENTS; i++)
{
delete p_clients[i];
}
cout << "Done.\n";
system("pause");
return 0;
}
结果
报错还没解决,之后复习再弄。
知识点
13.14 15 16
//继承和动态内存分配
#pragma once
#ifndef DMA_H_
#define DMA_H_
#include <iostream>
using namespace std;
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 ostream & operator<<(ostream & os, const baseDMA & rs);
};
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 ostream & operator<<(ostream & os, const lacksDMA & rs);
};
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 ostream & operator<<(ostream & os,
const hasDMA & rs);
};
#endif // !DMA_H_
#define _CRT_SECURE_NO_WARNINGS
#include <cstring>
#include "dma.h"
baseDMA::baseDMA(const char * l, int r)
{
label = new char[strlen(l) + 1];
strcpy(label, l);
rating = r;
}
baseDMA::baseDMA(const baseDMA & rs)
{
label = new char[strlen(rs.label) + 1];
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[strlen(rs.label) + 1];
strcpy(label, rs.label);
rating = rs.rating;
return *this;
}
ostream & operator<<(ostream & os, const baseDMA & rs)
{
os << "Label: " << rs.label << endl;
os << "Rating: " << rs.rating << endl;
return os;
}
lacksDMA::lacksDMA(const char * c, const char * l, int r)
:baseDMA(l, r)
{
strncpy(color, c, 39);
color[39] = '\0';
}
lacksDMA::lacksDMA(const char * c, const baseDMA & rs)
: baseDMA(rs)
{
strncpy(color, c, COL_LEN - 1);
color[COL_LEN - 1] = '\0';
}
ostream & operator<<(ostream & os, const lacksDMA & ls)
{
os << (const baseDMA &)ls;
os << "Color: " << ls.color << endl;
return os;
}
hasDMA::hasDMA(const char * s, const char * l, int r)
:baseDMA(l, r)
{
style = new char[strlen(s) + 1];
strcpy(style, s);
}
hasDMA::hasDMA(const char * s, const baseDMA & rs)
: baseDMA(rs)
{
style = new char[strlen(s) + 1];
strcpy(style, s);
}
hasDMA::hasDMA(const hasDMA & hs)
{
style = new char[strlen(hs.style) + 1];
strcpy(style, hs.style);
}
hasDMA::~hasDMA()
{
delete[] style;
}
hasDMA & hasDMA::operator=(const hasDMA & hs)
{
if (this == &hs)
return *this;
baseDMA::operator=(hs);
delete[] style;
style = new char[strlen(hs.style) + 1];
strcpy(style, hs.style);
return *this;
}
ostream & operator<<(ostream & os, const hasDMA & hs)
{
os << (const baseDMA &)hs;
os << "Style: " << hs.style << endl;
return os;
}
#include <iostream>
#include "dma.h"
int main()
{
//实例化对象
baseDMA shirt("Portabelly", 8);
lacksDMA balloon("red", "Blimpo", 4);
hasDMA map("Mercator", "Buffalo Keys", 5);
cout << "Displaying baseDMA object:\n";
cout << shirt << endl;
cout << "Displaying lacksDMA object:\n";
cout << balloon << endl;
cout << "Displaying hasDMA object:\n";
cout << map << endl;
lacksDMA balloon2(balloon);
cout << "Result of lacksDMA copy:\n";
cout << balloon2 << endl;
hasDMA map2;
map2 = map;
cout << "Result of hasDMA assignment:\n";
cout << map2 << endl;
return 0;
}
结果
知识点
1.继承和动态内存分配
总结
继承,多态,封装,还得再搞几遍。