1.pair.h
#pragma once
#include <iostream>
#include <string>
template<class T1,class T2>
class Pair
{
public:
Pair() {}
Pair(const T1& aval,const T2& bval):a(aval),b(bval){}
T1 first()const { return a; }
T2 second()const { return b; }
private:
T1 a;
T2 b;
};
wine.h
#pragma once
#include <iostream>
#include <valarray>
#include <string>
#include "Pair.h"
using namespace std;
typedef std::valarray<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;
class Wine
{
public:
Wine();
~Wine();
Wine(const char* label, int y);
Wine(const char* label, int y,const int yr[],const int bot[]);
int sum();
string& Label() { return m_sLabel; }
void Show();
void GetBottles();
private:
string m_sLabel;
int m_nNum;
PairArray m_bottoles;
};
wine.cpp
#include "Wine.h"
Wine::Wine()
{
m_sLabel = "";
m_nNum = 0;
}
Wine::~Wine()
{
}
Wine::Wine(const char* label, int y) {
m_sLabel = *label;
m_nNum = y;
ArrayInt year = ArrayInt(y);
ArrayInt bot = ArrayInt(y);
m_bottoles = PairArray(ArrayInt(y), ArrayInt(y));
for (int i = 0; i < y; ++i) {
m_bottoles.first()[i] = 0;
m_bottoles.second()[i] = 0;
}
}
Wine::Wine(const char* label, int y, const int yr[], const int bot[]) {
m_sLabel = *label;
m_nNum = y;
ArrayInt year = ArrayInt(m_nNum);
ArrayInt bott = ArrayInt(m_nNum);
for (int i = 0; i < y; ++i) {
year[i] = yr[i];
bott[i] = bot[i];
}
m_bottoles = PairArray(year,bott);
}
int Wine::sum() {
int sum = 0;
for (int i = 0; i < m_nNum; ++i) {
sum += m_bottoles.second()[i];
}
return sum;
}
void Wine::Show() {
cout << "Wine: " << m_sLabel << endl;
cout << " Year Bottoles" << endl;
for (int i = 0; i < m_nNum; ++i)
cout << " "<< m_bottoles.first()[i] <<" " << m_bottoles.second()[i]<< endl;
}
void Wine::GetBottles() {
cout << "Enter " << m_sLabel << " data for " << m_nNum << " year(s):" << endl;
ArrayInt year = ArrayInt(m_nNum);
ArrayInt bot = ArrayInt(m_nNum);
for (int i = 0; i < m_nNum; ++i) {
cout << "Enter year: ";
cin >> year[i];
cout << "Enter bottles for that year: ";
cin >> bot[i];
}
m_bottoles = PairArray(year, bot);
}
main函数:
#include <assert.h>
#include <iostream>
#include "Wine.h"
using namespace std;
int main()
{
cout << "Enter name of wine:";
char lab[50];
cin.getline(lab, 50);
cout << "Enter numer of years:";
int yrs;
cin >> yrs;
Wine holding(lab, yrs);
holding.GetBottles();
holding.Show();
const int YRS = 3;
int y[YRS] = { 1993,1995,1998 };
int b[YRS] = { 48,60,72 };
Wine more("Gushing Grape Red", YRS, y, b);
more.Show();
cout << "Total bottles for " << more.Label() << ": " << more.sum() << endl;
cout << "Bye\n";
return 0;
}
2.pair.h修改为:
#pragma once
#include <iostream>
#include <string>
template<class T1,class T2>
class Pair
{
public:
Pair() {}
Pair(const T1& aval,const T2& bval):a(aval),b(bval){}
T1 first()const { return a; }
T2 second()const { return b; }
void Set(const T1& aval, const T2& bval) { a = aval; b = bval; }
private:
T1 a;
T2 b;
};
wine.h:
#pragma once
#include <iostream>
#include <valarray>
#include <string>
#include "Pair.h"
using namespace std;
typedef std::valarray<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;
class Wine2:public PairArray,public string
{
public:
Wine2();
~Wine2();
Wine2(const char* label, int y);
Wine2(const char* label, int y, const int yr[], const int bot[]);
int sum();
string& Label() { return (string&)*this; }
void Show();
void GetBottles();
private:
int m_nNum;
};
wine.cpp:
#include "Wine2.h"
Wine2::Wine2()
{
}
Wine2::~Wine2()
{
}
Wine2::Wine2(const char* label, int y)
:string(label),PairArray(ArrayInt(y),ArrayInt(y)) {
m_nNum = y;
for (int i = 0; i < y; ++i) {
PairArray::first()[i] = 0;
PairArray::second()[i] = 0;
}
}
Wine2::Wine2(const char* label, int y, const int yr[], const int bot[])
:string(label), PairArray(ArrayInt(y), ArrayInt(y)) {
m_nNum = y;
ArrayInt year = ArrayInt(m_nNum);
ArrayInt bott = ArrayInt(m_nNum);
for (int i = 0; i < y; ++i) {
year[i] = yr[i];
bott[i] = bot[i];
}
PairArray::Set(year,bott);
}
int Wine2::sum() {
int sum = 0;
for (int i = 0; i < m_nNum; ++i) {
sum += PairArray::second()[i];
}
return sum;
}
void Wine2::Show() {
cout << "Wine: " << (const string)*this << endl;
cout << " Year Bottoles" << endl;
for (int i = 0; i < m_nNum; ++i)
cout << " " << PairArray::first()[i] << " " << PairArray::second()[i] << endl;
}
void Wine2::GetBottles() {
cout << "Enter " << (const string)*this << " data for " << m_nNum << " year(s):" << endl;
ArrayInt year = ArrayInt(m_nNum);
ArrayInt bot = ArrayInt(m_nNum);
for (int i = 0; i < m_nNum; ++i) {
cout << "Enter year: ";
cin >> year[i];
cout << "Enter bottles for that year: ";
cin >> bot[i];
}
PairArray::Set(year, bot);
}
main函数与之前相同。
3.模板类定义和实现都要放在头文件中,不然编译会报错。
queuetp.h:
#pragma once
#include <iostream>
using namespace std;
template<class T>
class QueueTp
{
public:
QueueTp(int qs = Q_SIZE);
~QueueTp();
bool IsEmpty()const;
bool IsFull()const;
int count() const;
bool enqueue(const T& item);
bool dequeue(T& item);
private:
struct Node
{
T item;
Node* next;
};
enum { Q_SIZE = 10 };
Node* front;
Node* rear;
int items;
const int qsize;
QueueTp(const QueueTp& q):qsize(0){}
QueueTp& operator=(const QueueTp& q) { return *this; }
};
template<class T>
QueueTp<T>::QueueTp(int qs) :qsize(qs){
front = rear = NULL;
items = 0;
}
template<class T>
QueueTp<T>::~QueueTp() {
Node* temp;
while (front != NULL) {
temp = front;
front = front->next;
delete temp;
}
}
template<class T>
bool QueueTp<T>::IsEmpty()const { return items == 0; }
template<class T>
bool QueueTp<T>::IsFull()const { return items == qsize; }
template<class T>
int QueueTp<T>::count() const { return items; }
template<class T>
bool QueueTp<T>::enqueue(const T& item) {
if (IsFull()) {
cout << "queue is already full!\n";
return false;
}
Node* add = new Node;
add->item = item;
add->next = NULL;
items++;
if (front == NULL)
front = add;
else
rear->next = add;
rear = add;
return true;
}
template<class T>
bool QueueTp<T>::dequeue(T& item) {
if (IsEmpty()) {
cout << "queue is empty!\n";
return false;
}
item = front->item;
items--;
Node* temp = front;
front = front->next;
delete temp;
if (items == 0)
rear = NULL;
return true;
}
worker.h:
#pragma once
#include <string>
using namespace std;
class Worker
{
public:
Worker():fullname("no one"),id(0L){}
Worker(const string& s,long n):fullname(s),id(n){}
virtual ~Worker();
virtual void Set() = 0;
virtual void Show() = 0;
protected:
virtual void Data()const;
virtual void Get();
private:
string fullname;
long id;
};
class Waiter :virtual public Worker {
public:
Waiter():Worker(),panache(0){}
Waiter(const string& s,long n,int p = 0):Worker(s,n),panache(p){}
Waiter(const Worker& wk,int p = 0) :Worker(wk),panache(p) {}
void Set();
void Show();
protected:
void Data()const;
void Get();
private:
int panache;
};
class Singer:virtual public Worker
{
public:
Singer() :Worker(), voice(other) {}
Singer(const string& s, long n, int v = other) :Worker(s, n), voice(v) {}
Singer(const Worker& wk, int v = other) :Worker(wk), voice(v) {}
void Set();
void Show();
protected:
enum{other,alto,contralto,soprano,bass,baritone,tenor};
enum{Vtypes = 7};
void Data()const;
void Get();
private:
static char* pv[Vtypes];
int voice;
};
class SingingWaiter:public Singer, public Waiter {
public:
SingingWaiter(const string& s, long n, int p = 0,int v = other)
:Worker(s,n),Waiter(s,n,p),Singer(s,n,v){}
SingingWaiter(const Worker& wk, int p = 0, int v = other)
:Worker(wk),Waiter(wk,p),Singer(wk,v){}
SingingWaiter(const Worker& wk, int p = 0)
:Worker(wk), Waiter(wk, p), Singer(wk) {}
SingingWaiter(){}
void Set();
void Show();
protected:
void Data()const;
void Get();
};
worker.cpp:
#include <iostream>
#include "Worker.h"
using namespace std;
Worker::~Worker()
{
}
void Worker::Data()const {
cout << "Name:" << fullname << endl;
cout << "ID: " << id << endl;
}
void Worker::Get() {
cin >> fullname;
cout << "Enter worker's id: ";
cin >> id;
while (cin.get() != '\n')
continue;
}
void Waiter::Set() {
cout << "Enter waiter's name: ";
Worker::Get();
Get();
}
void Waiter::Show(){
cout << "Category: waiter\n";
Worker::Data();
Data();
}
void Waiter::Data()const {
cout << "panache rating: " << panache << endl;
}
void Waiter::Get() {
cout << "Enter waiter's panache rating: ";
cin >> panache;
while (cin.get() != '\n')
continue;
}
char* Singer::pv[Singer::Vtypes] = { "other","alto","contralto","soprano"
,"bass","baritone","tenor" };
void Singer::Set() {
cout << "Enter singer's name: ";
Worker::Get();
Get();
}
void Singer::Show(){
cout << "Category: singer\n";
Worker::Data();
Data();
}
void Singer::Data()const {
cout << "Vocal range: " << pv[voice] << endl;
}
void Singer::Get() {
cout << "Enter number for singer's vocal range: \n";
int i = 0;
for (i = 0; i < Vtypes; ++i) {
cout << i << ":" << pv[i] << " ";
if (i % 4 == 3)
cout << endl;
}
if (i % 4 != 0)
cout << endl;
cin >> voice;
while (cin.get() != '\n')
continue;
}
void SingingWaiter::Set() {
cout << "Enter singing waiter's name: ";
Worker::Get();
Get();
}
void SingingWaiter::Show() {
cout << "Category: singing waiter\n";
Worker::Data();
Data();
}
void SingingWaiter::Data()const {
Singer::Data();
Waiter::Data();
}
void SingingWaiter::Get() {
Waiter::Get();
Singer::Get();
}
main:
#include <iostream>
#include "Worker.h"
#include "QueueTp.h"
const int SIZE = 20;
using namespace std;
int main()
{
QueueTp<Worker*>* wo = new QueueTp<Worker*>(SIZE);
for (int i = 0; i < SIZE+1; ++i) {
char choice;
cout << "Enter the employee category:\n"
<< "w:waiter s:singer t:singing waiter q:quit\n";
cin >> choice;
while (strchr("wstq", choice) == NULL) {
cout << "Please enter a w,s,t, or q:";
cin >> choice;
}
if (choice == 'q')
break;
Waiter * w;
Singer* s;
SingingWaiter * sw;
switch (choice)
{
case 'w':
w = new Waiter;
w->Set();
wo->enqueue(w);
break;
case 's':
s = new Singer;
s->Set();
wo->enqueue(s);
break;
case 't':
sw = new SingingWaiter;
sw->Set();
wo->enqueue(sw);
break;
default:
assert(false);
break;
}
cout << "queue has " << wo->count() << " members.\n";
}
Worker* temp;
wo->dequeue(temp);
temp->Show();
cout << "Bye.\n";
return 0;
}
4. person.h:
#pragma once
#include <string>
#include <iostream>
using namespace std;
class Person
{
public:
Person(string f, string l) :first_name(f), last_name(l) {}
~Person();
virtual void Show();
private:
string first_name;
string last_name;
};
class Gunslinger : virtual public Person
{
public:
Gunslinger(string f, string l,int d):Person(f,l),dents(d){}
double Draw();
virtual void Show();
private:
int dents;
};
class PokerPlayer :virtual public Person
{
public:
PokerPlayer(string f, string l) :Person(f,l) {}
int Draw();
};
class BadDude : public PokerPlayer,public Gunslinger
{
public:
BadDude(string f, string l, int d):Person(f,l),PokerPlayer(f,l),Gunslinger(f,l,d){}
double Gdraw();
int Cdraw();
void Show();
};
person.cpp:
#include "Person.h"
void Person::Show()
{
cout << "the person's fullname is " << last_name << " " << first_name <<endl;
}
Person::~Person()
{
}
double Gunslinger::Draw() { return (rand() % 10) / 10; }
void Gunslinger::Show(){
cout << "the Gunslinger's time is " << Draw() << " ,there are " << dents << " dents in his gun.";
Person::Show();
}
int PokerPlayer::Draw() { return rand() % 52; }
int BadDude::Cdraw() { return PokerPlayer::Draw(); }
void BadDude::Show() {
cout << "the BadDude's next card is " << Gdraw() << " ,time is " << Cdraw() << ".";
Person::Show();
}
double BadDude::Gdraw(){ return Gunslinger::Draw();}
main:
#include <iostream>
#include <vector>
#include "Person.h"
const int SIZE = 20;
using namespace std;
int main()
{
std::vector<Person*> ps;
for (int i = 0; i < SIZE; ++i) {
char choice;
cout << "Enter the person category:\n"
<< "g:Gunslinger p:PokerPlayer b:BadDude q:quit\n";
cin >> choice;
while (strchr("gpbq", choice) == NULL) {
cout << "Please enter g p,b,or q:";
cin >> choice;
}
if (choice == 'q')
break;
Gunslinger * g;
PokerPlayer* pp;
BadDude * bd;
string l, f;
int d;
cout << "Enter the person's lastname:";
cin >> l;
cout << "Enter the person's firstname:";
cin >> f;
switch (choice)
{
case 'g':
cout << "Enter the dents' number:";
cin >> d;
g = new Gunslinger(f,l,d);
ps.push_back(g);
break;
case 'p':
pp = new PokerPlayer(f,l);
ps.push_back(pp);
break;
case 'b':
cout << "Enter the dents' number:";
cin >> d;
bd = new BadDude(f, l, d);
ps.push_back(bd);
break;
default:
assert(false);
break;
}
cout << endl;
}
cout << "All of people are:\n";
for (auto p : ps) {
p->Show();
}
cout << "Bye.\n";
return 0;
}
5. employee.cpp
#include<iostream>
#include "employee.h"
using namespace std;
abstr_emp::abstr_emp() {
fname = "";
lname = "";
job = "";
}
abstr_emp::abstr_emp(const string& fn, const string& ln, const string& j):fname(fn),lname(ln),job(j) {}
void abstr_emp::ShowAll() const {
cout << "abstr_emp:" << endl;
cout << "first name is: " << fname << " last name is: " << lname << " job is: " << job << endl;
}
abstr_emp::~abstr_emp() {}
void abstr_emp::SetAll() {
cout << "Enter first name:";
getline(cin, fname);
cout << "Enter last name:";
getline(cin, lname);
cout << "Enter job:";
getline(cin, job);
}
ostream& operator<<(ostream& os, const abstr_emp& e) {
os << e.fname <<"."<< e.lname << e.job;
return os;
}
employee::employee():abstr_emp() {}
employee::employee(const string& fn, const string& ln, const string& j):abstr_emp(fn, ln, j) {}
void employee::ShowAll() const {
cout << "employee:" << endl;
abstr_emp::ShowAll();
}
void employee::SetAll() { abstr_emp::SetAll(); }
manager::manager():abstr_emp(), inchargeof(0) {}
manager::manager(const string& fn, const string& ln, const string& j, int ico) :abstr_emp(fn, ln, j) { inchargeof = ico; }
manager::manager(const abstr_emp& e, int ico):abstr_emp(e) { inchargeof = ico; }
manager::manager(const manager& m):abstr_emp(m) { inchargeof = m.inchargeof; }
void manager::ShowAll() const {
cout << "manager:" << endl;
abstr_emp::ShowAll();
cout << "inchargeof is: " << inchargeof << endl;
}
void manager::SetAll() {
abstr_emp::SetAll();
cout << "Enter inchargeof:";
cin>> inchargeof;
}
fink::fink():abstr_emp(),reportsto("") {}
fink::fink(const string& fn, const string& ln, const string& j, const string& rpo) :abstr_emp(fn, ln, j) { reportsto = rpo; }
fink::fink(const abstr_emp& e, const string& rpo):abstr_emp(e) {reportsto = rpo;}
fink::fink(const fink& e) : abstr_emp(e){ reportsto = e.reportsto; }
void fink::ShowAll() const {
cout << "fink:" << endl;
abstr_emp::ShowAll();
cout << "reportsto is: " << reportsto << endl;
}
void fink::SetAll() {
abstr_emp::SetAll();
cout << "Enter reportsto:";
getline(cin,reportsto);
}
highfink::highfink():abstr_emp(),manager(),fink() {}
highfink::highfink(const string& fn, const string& ln, const string& j, const string& rpo, int ico):abstr_emp(fn,ln,j),manager(fn,ln,j,ico),fink(fn,ln,j,rpo){}
highfink::highfink(const abstr_emp& e, const string& rpo, int ico):abstr_emp(e),manager(e,ico),fink(e,rpo) {}
highfink::highfink(const fink& e, int ico):abstr_emp(e),manager(e,ico),fink(e) {}
highfink::highfink(const manager& m, const string& rpo):abstr_emp(m),manager(m),fink(m,rpo) {}
highfink::highfink(const highfink& e):abstr_emp(e),manager(e),fink(e) {}
void highfink::ShowAll() const {
cout << "highfink:" << endl;
abstr_emp::ShowAll();
cout << "reportsto is: " << fink::ReportsTo() << "inchargeof is: " << manager::InChargeOf() << endl;;
}
void highfink::SetAll() {
manager::SetAll();
cout << "Enter reportsto:";
getline(cin, fink::ReportsTo());
}
employee.h:
#pragma once
#include <iostream>
#include <string>
using namespace std;
class abstr_emp {
public:
abstr_emp();
abstr_emp(const string& fn, const string& ln, const string& j);
virtual void ShowAll() const;
virtual void SetAll();
friend ostream& operator<<(ostream& os, const abstr_emp& e);
virtual ~abstr_emp() = 0;
private:
string fname;
string lname;
string job;
};
class employee:public abstr_emp
{
public:
employee();
employee(const string& fn, const string& ln, const string& j);
virtual void ShowAll() const;
virtual void SetAll();
};
class manager:virtual public abstr_emp
{
public:
manager();
manager(const string& fn, const string& ln, const string& j, int ico = 0);
manager(const abstr_emp& e, int ico);
manager(const manager& m);
virtual void ShowAll() const;
virtual void SetAll();
protected:
int InChargeOf()const { return inchargeof; }
int& InChargeOf(){ return inchargeof; }
private:
int inchargeof;
};
class fink:virtual public abstr_emp
{
public:
fink();
fink(const string& fn, const string& ln, const string& j,const string& rpo);
fink(const abstr_emp& e, const string& rpo);
fink(const fink& e);
virtual void ShowAll() const;
virtual void SetAll();
protected:
const string ReportsTo()const { return reportsto; }
string& ReportsTo(){ return reportsto; }
private:
string reportsto;
};
class highfink :public manager, public fink {
public:
highfink();
highfink(const string& fn, const string& ln, const string& j, const string& rpo,int ico);
highfink(const abstr_emp& e, const string& rpo,int ico);
highfink(const fink& e, int ico);
highfink(const manager& m, const string& rpo);
highfink(const highfink& e);
virtual void ShowAll() const;
virtual void SetAll();
};
main函数:
#include <iostream>
#include "employee.h"
const int SIZE = 5;
using namespace std;
int main()
{
employee em("Trip", "Harris", "Thumper");
cout << em << endl;
em.ShowAll();
manager ma("Amorphia", "Sindragon", "Nuancer", 5);
cout << ma << endl;
ma.ShowAll();
fink fi("Matt", "Oggs", "Oiler", "Juno Barr");
cout << fi << endl;
fi.ShowAll();
highfink hf(ma, "Curly Kew");
hf.ShowAll();
cout << "Press a key for next phase:\n";
cin.get();
highfink hf2;
hf2.SetAll();
cout << "Using an abstr_emp* pointer:\n";
abstr_emp* tr[4] = { &em,&fi,&hf,&hf2 };
for (int i = 0; i < 4; ++i)
tr[i]->ShowAll();
return 0;
}
输出为:
类本身会生成赋值操作符,例子中的所有类中没有指针成员,不需要深拷贝,可使用默认的赋值操作。
ShowAll和SetAll定义为虚拟的,在类继承中,子类可对这两个函数重写,不重写的子类调用基类的实现。
将abstr_emp定义为虚基类则多重继承(MI)时派生类就只有一个基类的子对象。
highfink类没有数据部分是因为继承自基类的数据成员满足该类的功能需求。
此处operator<<定义为友元,而友元函数不能继承,在需要的地方定义即可,不用担心继承关系而重定义以满足不同类的不同需求。
使用新的方法,则调用ShowAll时调用的是基类abstr_emp的。