【第十四章】C++ Primer plus 的编程练习题

// winec.h -- class Wine definition
#ifndef __WINEC_H__
#define __WINEC_H__
#include <string>
#include <valarray>
#include <utility>

class Wine
{
private:
	typedef std::valarray<int> ArrayInt;
	/* PairArray <=> Pair< std::valarray<int>, std::valarray<int> > */
	typedef std::pair<ArrayInt, ArrayInt> PairArray;
	std::string name;
	PairArray instan; // 代表instan对象的成员first和
			// second都是std::valarray<int>类型的对象;
public:
	// initialize label to l, number of years to y, //年份的个数
	// vintage years to yr[], bottles to bot[]
	Wine(const char * l, int y, const int yr[], const int bot[]);
	// initialize label to l, number of years to y, 
	// create array objects of length y
	Wine(const char * l, int y);
	void GetBottles();
	const std::string & Label() const;
	int sum() const;
	void show() const;
};

#endif /* __WINEC_H__ */

// winec.cpp -- class Wine for methods
#include <iostream>
#include "winec.h"

Wine::Wine(const char * l, int y, const int yr[], const int bot[])
{
	name = l;
	ArrayInt a(y);  // 等价于定义的 int a[3];
	ArrayInt b(y);  
	for (int i = 0; i < y; i++) {
		a[i] = yr[i];
		b[i] = bot[i];
	}
	instan = std::make_pair(a, b); // 根据a,b数组名生成一个pair临时对象
				// 然后根据instan默认的赋值函数将该临时对象的内容赋值给
	            // instan对象。当该函数执行完毕后,该临时对象会被释放掉。
}

Wine::Wine(const char * l, int y) 
{
	name = l;
	ArrayInt a(y);  // 等价于定义的 int a[3];
	ArrayInt b(y); 
	instan = std::make_pair(a, b);
}

void Wine::GetBottles()
{
	using std::cout;
	using std::endl;
	using std::cin;

	ArrayInt a(instan.first.size()); // 这里的a,b不是对象instan中的元素
	ArrayInt b(instan.second.size()); // 
	cout << "Enter " << name << " data for " 
		 << instan.first.size() << " year(s):\n";
	for (int i = 0; i < (int)instan.first.size(); i++) {
		cout << "Enter year: ";
		cin >> a[i];
		cout << "Enter bottles for that year: ";
		cin >> b[i];
	}
	instan = std::make_pair(a, b); // 根据a,b数组名生成一个pair临时对象
				// 然后根据instan默认的赋值函数将该临时对象的内容赋值给
	            // instan对象。当该函数执行完毕后,该临时对象会被释放掉。
}

const std::string & Wine::Label() const
{
	return name;
}

int Wine::sum() const
{
	int ans = 0;
	for (int i = 0; i < (int)instan.first.size(); i++)
		ans += instan.second[i];
	return ans;
}

void Wine::show() const
{
	std::cout << "Wine: " << name << std::endl;
	std::cout << "\t" << "Year" << "\t" << "Bottles" << std::endl;
	for (int i = 0; i < (int)instan.first.size(); i++)
		std::cout << "\t" << instan.first[i] << "\t" 
		          << instan.second[i] << std::endl;
}

/***********************************
	2017年12月7日13:44:54
	Athor:xiyuan255
	Course:C++
	Contain:pe14-1.cpp
			 winec.h
		     winec.cpp
	Reference: C++ Primer plus
		知识点:make_pair():
			无需写出型别, 就可以生成一个pair对象
			例:std::make_pair(42, '@');
			而不必费力写成:
			std::pair<int, char>(42, '@')
			当有必要对一个接受pair参数的函数传递两个值时, make_pair()尤其显得方便, 
	说明:C++ Primer plus第十四章的第一题练习题
		 【 参考 P598 】
*************************************/
// pe14-1.cpp -- using Wine class with containment
#include <iostream>
#include "winec.h"

int main ( void )
{
	using std::cin;
	using std::cout;
	using std::endl;

	cout << "Enter name of wine: ";
	char lab[50];
	cin.getline(lab, 50);
	cout << "Enter number of years: ";
	int yrs;
	cin >> yrs;

	Wine holding(lab, yrs);  // store label, years, give arrays yrs elements
	holding.GetBottles();    // solicit input for year, bottle count
	holding.show();          // display object contents

	const int YRS = 3;
	int y[YRS] = { 1993, 1995, 1998 };
	int b[YRS] = { 48, 60, 72 };
	// create new object, initialize using data in arrays y and b
	Wine more("Gushing Grape Red", YRS, y, b);
	more.show();
	cout << "Total bottles for " << more.Label()   // use lableVal() moethid
		 << ": " << more.sum() << endl;               // use sum() method
	cout << "Bye.\n";

	return 0;
}

/**
输出结果:
	Enter name of wine: Gully Wash
	Enter number of years: 4
	Enter Gully Wash data for 4 year(s):
	Enter year: 1988
	Enter bottles for that year: 42
	Enter year: 1994
	Enter bottles for that year: 58
	Enter year: 1998
	Enter bottles for that year: 122
	Enter year: 2001
	Enter bottles for that year: 144
	Wine: Gully Wash
			Year    Bottles
			1988    42
			1994    58
			1998    122
			2001    144
	Wine: Gushing Grape Red
			Year    Bottles
			1993    48
			1995    60
			1998    72
	Total bottles for Gushing Grape Red: 180
	Bye.
*/

// winec2.h -- class Wine definition
#ifndef __WINEC2_H__
#define __WINEC2_H__
#include <string>
#include <valarray>

typedef std::valarray<int> ArrayInt;
/* pair<>是一个模板类,只有模板具体化,才能生成一个类
 * 如下类名为:std::pair<ArrayInt, ArrayInt>,而不是std::pair */
typedef std::pair<ArrayInt, ArrayInt> PairArray;

class Wine : private std::string, private PairArray
{
public:
	Wine() { }
	// initialize label to l, number of years to y,
	// vintage years to yr[], bottles to bot[]
	Wine(const char * l, int y, const int yr[], const int bot[]);
	// initialize label to l, number of years to y, 
	// create array objects of length y
	Wine(const char * l, int y);
	void GetBottles();
	const std::string & Label() const;
	int sum() const;
	void show() const;
};

#endif /* __WINEC2_H__ */

// winec2.cpp -- class Wine for methods
#include <iostream>
#include "winec2.h"

// typedef std::valarray<int> ArrayInt;
Wine::Wine(const char * l, int y, const int yr[], const int bot[])
	: std::string(l), PairArray(ArrayInt(yr, y), ArrayInt(bot, y))
{ // ArrayInt(yr, y)的含义是,生成一个int arrayname[y];的数组,
  // 且数组元素的初始值等于yr[]数组里面的值。
}

Wine::Wine(const char * l, int y) 
	: std::string(l), PairArray(ArrayInt(y), ArrayInt(y))
{
}

void Wine::GetBottles()
{
	using std::cout;
	using std::endl;
	using std::cin;

	ArrayInt a(PairArray::first.size()); // 这里的a,b不是对象instan中的元素
	ArrayInt b(PairArray::second.size()); 
	cout << "Enter " << (const std::string &)*this << " data for " 
		 << PairArray::first.size() << " year(s):\n";
	for (int i = 0; i < (int)PairArray::first.size(); i++) {
		cout << "Enter year: ";
		cin >> PairArray::first[i];
		cout << "Enter bottles for that year: ";
		cin >> PairArray::second[i];
	}
	//instan = std::make_pair(a, b); // 根据a,b数组名生成一个pair临时对象
				// 然后根据instan默认的赋值函数将该临时对象的内容赋值给
	            // instan对象。当该函数执行完毕后,该临时对象会被释放掉。
}

const std::string & Wine::Label() const
{
	return (const std::string &)*this;
}

int Wine::sum() const
{
	int ans = 0;
	for (int i = 0; i < (int)PairArray::first.size(); i++)
		ans += PairArray::second[i];
	return ans;
}

void Wine::show() const
{
	std::cout << "Wine: " << (const std::string &)*this << std::endl;
	std::cout << "\t" << "Year" << "\t" << "Bottles" << std::endl;
	for (int i = 0; i < (int)PairArray::first.size(); i++)
		std::cout << "\t" << PairArray::first[i] << "\t" 
		          << PairArray::second[i] << std::endl;
}

/***********************************
	2017年12月7日14:22:45
	Athor:xiyuan255
	Course:C++
	Contain:pe14-2.cpp
			 winec2.h
		     winec2.cpp
	Reference: C++ Primer plus
		知识点:make_pair():
			无需写出型别, 就可以生成一个pair对象
			例:std::make_pair(42, '@');
			而不必费力写成:
			std::pair<int, char>(42, '@')
			当有必要对一个接受pair参数的函数传递两个值时, make_pair()
			尤其显得方便;
	说明:C++ Primer plus第十四章的第二题练习题
		 【 参考 P598 】
*************************************/
// pe14-1.cpp -- using Wine class with containment
#include <iostream>
#include "winec2.h"

int main ( void )
{
	using std::cin;
	using std::cout;
	using std::endl;

	cout << "Enter name of wine: ";
	char lab[50];
	cin.getline(lab, 50);
	cout << "Enter number of years: ";
	int yrs;
	cin >> yrs;

	Wine holding(lab, yrs);  // store label, years, give arrays yrs elements
	holding.GetBottles();    // solicit input for year, bottle count
	holding.show();          // display object contents

	const int YRS = 3;
	int y[YRS] = { 1993, 1995, 1998 };
	int b[YRS] = { 48, 60, 72 };
	// create new object, initialize using data in arrays y and b
	Wine more("Gushing Grape Red", YRS, y, b);
	more.show();
	cout << "Total bottles for " << more.Label()   // use lableVal() moethid
		 << ": " << more.sum() << endl;               // use sum() method
	cout << "Bye.\n";

	return 0;
}

/**
输出结果:
	Enter name of wine: Gully Wash
	Enter number of years: 4
	Enter Gully Wash data for 4 year(s):
	Enter year: 1988
	Enter bottles for that year: 42
	Enter year: 1994
	Enter bottles for that year: 58
	Enter year: 1998
	Enter bottles for that year: 122
	Enter year: 2001
	Enter bottles for that year: 144
	Wine: Gully Wash
			Year    Bottles
			1988    42
			1994    58
			1998    122
			2001    144
	Wine: Gushing Grape Red
			Year    Bottles
			1993    48
			1995    60
			1998    72
	Total bottles for Gushing Grape Red: 180
	Bye.
*/

// queuetp.h -- template class QueueTp definition
template <typename T>
class QueueTp
{
private:
	static const int LEN = 10;
	T * listHead;
	T * listTail;
    T * data;
public:
	QueueTp(int len = LEN) { data = new T[len]; listHead = listTail = data; }
	~QueueTp() { delete[] data; }
	bool enQueue(const T & item);
	bool deQueue(T & item);
	T newQueue() const { return *(listTail-1); }
	bool isFull() const { return listTail == data + sizeof(data); }
	bool isEmpty() const { return listTail == listHead; }
};

template <typename T>
bool QueueTp<T>::enQueue(const T & item)
{
	if (isFull())
		return false;
	*listTail = item;
	listTail++;
	return true;
}

template <typename T>
bool QueueTp<T>::deQueue(T & item)
{
	if (isFull())
		return false;
	item = *listHead;
	listHead++;
	return true;
}


/* programNo14.10 */
// workermi.h -- working classes with MI(multiple inheritance)
#ifndef __WORKERMI_H__
#define __WORKERMI_H__

#include <string>

class Worker   // an abstract base class
{
private:
	std::string fullname;
	long id;
protected:
	virtual void data() const;
	virtual void get();
public:
	Worker() : fullname("no one"), id(0L) { }
	Worker(const std::string & s, long n)
		: fullname(s), id(n) { }
	virtual ~Worker() = 0;  // pure virtual destructor (纯析构函数)
	virtual void set() = 0; // (纯析构函数)
	virtual void show() const = 0; // (纯析构函数)
};

class Waiter : virtual public Worker
{ // 表示Waiter公有继承的虚基类是Worker
private:
	int panache;
protected:
	void data() const;
	void get();
public:
	Waiter() : Worker(), panache(0) { }
	Waiter(const std::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() const;
};

class Singer : virtual public Worker 
{ // 表示Singer公有继承的虚基类是Worker
protected:
	enum { other, alto, contralto, soprano,
	       bass, baritone, tenor };
	enum { Vtypes = 7 };
	void data() const;
	void get();
private:
	static char *pv[Vtypes];   // string equivs of voice tyoes
	int voice;
public:
	Singer() : Worker(), voice(other) { }
	Singer(const std::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() const;
};

// 因为Waiter和Singer都是公有继承的虚基类是Worker,所以
// 二级派生类Waiter和Singer将保存同一份基类Worker的副本。
// 所以下面这样继承,SingingWaiter类只是继承了一份Worker
// 的副本,而不是两份。
// multiple inheritance
class SingingWaiter : public Singer, public Waiter
{
protected:
	void data() const;
	void get();
public:
	SingingWaiter() { }
	/* 当类继承的基类为虚基类时,编译器将禁止信息通过中间类传递
	 * 给基类,以调用基类的构造函数来创建对象功能。所以构造函数
	 * Waiter(s,n, p)和Singer(s, n, v)并不会构造基类对象,因此
	 * 需要显式调用基类构造函数,如没有显式,则调用基类默认的
	 * 构造函数。这种方式的调用只有在基类是虚基类下才有效。 */
	SingingWaiter(const std::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 Waiter & wt, int v = other)
		: Worker(wt), Waiter(wt), Singer(wt, v) { }
	SingingWaiter(const Singer & wt, int p = 0)
		: Worker(wt), Waiter(wt, p), Singer(wt) { }
	void set();
	void show() const;
};

#endif /* __WORKERMI_H__ */

/* programNo14.11 */
// workermi.cpp -- working class methods with MI(multiple inheritance)
#include "workermi.h"
#include <iostream>
using std::cout;
using std::cin;
using std::endl;

// Worker methods
// must implment vritual destructor, even if pure
Worker::~Worker() { } // 析构函数必须被实现,即使它是纯虚析构函数

// protected methods
void Worker::data() const
{
	cout << "Name: " << fullname << "\n";
	cout << "Employee ID: " << id << "\n";
}

void Worker::get()
{
	getline(cin, fullname);
	cout << "Enter worker's ID: ";
	cin >> id;
	while (cin.get() != '\n')
		continue;
}

// Waiter methods
void Waiter::set()
{
	cout << "Enter waiter's name: ";
	Worker::get();
	get();
}

void Waiter::show() const
{
	cout << "Category waiter\n";
	Worker::data();
	data();
}

// protected methods
void Waiter::data() const
{
	cout << "Panache rating: " << panache << "\n";
}

void Waiter::get()
{
	cout << "Enter Waiter's panache rating: ";
	cin >> panache;
	while (cin.get() != '\n')
		continue;
}

// Singer methods
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() const
{
	cout << "Category singer\n";
	Worker::data();
	data();
}

// protected methods
void Singer::data() const
{
	cout << "Vocal range: "<< pv[voice] << endl;
}

void Singer::get()
{
	cout << "Enter number for singer's vocal range:\n";
	int i;
	for (i = 0; i < Vtypes; i++) {
		cout << i << ": " << pv[i] << "  ";
		if (i % 4 == 3)
			cout << endl;
	}
	if (i % 4 != 0)
		cout << endl;
	while (cin >> voice && (voice < 0 || voice >= Vtypes))
		cout << "Please enter a value >= 0 and < " << Vtypes << endl;
	while (cin.get() != '\n')
		continue;
}

/* 在这里为何要将show分离出data函数,是因为Waiter和Singer类的
 * show函数都包含了Worker::data()函数,如果直接调用Waiter和
 * Singer类的show方法,这将造成Worker::data()函数被调用两次,
 * 所以在这里应当要将它分离出来。 */
// SingingWaiter methods
void SingingWaiter::data() const
{
	Waiter::data();
	Singer::data();
}

/* 这里的从set()方法分离出的get()方法的原因,同上 */
void SingingWaiter::get()
{
	Waiter::get();
	Singer::get();
}

void SingingWaiter::set()
{
	cout << "Enter singing waiter's name: ";
	Worker::get();
	get();
}

void SingingWaiter::show() const
{
	cout << "Category: singing waiter\n";
	Worker::data();
	data();
}

/***********************************
	2017年12月8日08:37:12
	Athor:xiyuan255
	Course:C++
	Contain:workmi2.cpp
			 queuetp.h
			 workermi.h
		     workermi.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十四章的第三题练习题
		 【 参考 P598 】
*************************************/
// workmi.cpp -- multiple inheritance
// compile with workermi.cpp
#include <iostream>
#include <cstring>
#include "workermi.h"
#include "queuetp.h"

int main()
{
	using std::cin;
	using std::cout;
	using std::endl;
	using std::strchr;
	QueueTp<Worker *> lolas;
	int ct;
	while (!lolas.isFull()) {
		char choice;
		cout << "[ Enter the employee category: ]\n"
				<< "w: waiter s: singer "
				<< "t: singing waiter q: quit\n";
		cin >> choice;
		/* 原型extern char * strchr(const char * s, char c)
			* 查找字符串s中首次出现字符c的位置,如不存在返回0 */
		while (strchr("wstq", choice) == NULL) {
			cout << "Please enter a w, s, t, or q: ";
			cin >> choice;
		}
		if ('q' == choice)
			break;
		switch (choice) {
			case 'w': lolas.enQueue(new Waiter); // 调用默认构造函数
				break;
			case 's': lolas.enQueue(new Singer); // 调用默认构造函数
				break;
			case 't': lolas.enQueue(new SingingWaiter);// 调用默认构造函数
				break;
		}
		cin.get(); // 获取‘\n’字符
		lolas.newQueue()->set();
	}
	cout << "\nHere is your staff:\n";
	Worker * pwok;
	while (!lolas.isEmpty()) {
		lolas.deQueue(pwok);
		cout << endl;
		pwok->show();
		delete pwok;
	}
	cout << "Bye.\n";

	return 0;
}

/**
输出结果:
	[ Enter the employee category: ]
	w: waiter s: singer t: singing waiter q: quit
	w
	Enter waiter's name: Wally Slipshod
	Enter worker's ID: 1040
	Enter Waiter's panache rating: 4
	[ Enter the employee category: ]
	w: waiter s: singer t: singing waiter q: quit
	s
	Enter singer's name: Sinclair Parma
	Enter worker's ID: 1044
	Enter number for singer's vocal range:
	0: other  1: alto  2: contralto  3: soprano
	4: bass  5: baritone  6: tenor
	5
	[ Enter the employee category: ]
	w: waiter s: singer t: singing waiter q: quit
	t
	Enter singing waiter's name: Natasha Gargalova
	Enter worker's ID: 1021
	Enter Waiter's panache rating: 6
	Enter number for singer's vocal range:
	0: other  1: alto  2: contralto  3: soprano
	4: bass  5: baritone  6: tenor
	3
	[ Enter the employee category: ]
	w: waiter s: singer t: singing waiter q: quit
	q

	Here is your staff:

	Category waiter
	Name: Wally Slipshod
	Employee ID: 1040
	Panache rating: 4

	Category singer
	Name: Sinclair Parma
	Employee ID: 1044
	Vocal range: baritone

	Category: singing waiter
	Name: Natasha Gargalova
	Employee ID: 1021
	Panache rating: 6
	Vocal range: soprano
	Bye.
*/

// person.h -- class Person definition
#ifndef __PERSON_H__
#define __PERSON_H__
#include <string>

class Person 
{
private:
	std::string firstname;
	std::string lastname;
public:
	Person(const std::string & fr = "fr none", 
		const std::string & ls = "ls none");
	virtual ~Person() { }
	virtual void show() const;
};

class Gunslmger : virtual public Person
{
private:
	int nicknumber;
	double drawTime;
public:
	Gunslmger(const std::string & fr, 
		const std::string & ls, int nn, double dt);
	double draw() { return drawTime; }
	void show() const;
};

class PokerPlayer : virtual public Person
{
public:
	PokerPlayer() { }
	PokerPlayer(const std::string & fr, const std::string & ls);
	int draw();
};

class BadDude : public Gunslmger, public PokerPlayer
{
public:
	BadDude(const std::string & fr, 
		const std::string & ls, int nn, double dt);
	double Gdraw();
	int Cdraw();
	void show();

};

#endif /* __PERSON_H__ */

// person.cpp -- class Person methods
#include <iostream>
#include "person.h"
#include <ctime>  // for time()
#include <cstdlib>  // rand(), srand()

using std::cout;
using std::endl;

// class Person methods
Person::Person(const std::string & fr, const std::string & ls)
{
	firstname = fr;
	lastname = ls;
}

void Person::show() const
{
	cout << "FirstName: " << firstname << endl;
	cout << "LastName: " << lastname << endl;
}

// class Gunslmger methods
Gunslmger::Gunslmger(const std::string & fr, const std::string & ls,
	int nn, double dt) : Person(fr, ls), nicknumber(nn), drawTime(dt)
{
}

void Gunslmger::show() const
{
	Person::show();
	cout << "NickNumber" << nicknumber << endl;
	cout << "DrawTime" << drawTime << endl;
}

// class PokerPlayer methods
PokerPlayer::PokerPlayer(const std::string & fr, 
		const std::string & ls) : Person(fr, ls)
{
}

int PokerPlayer::draw()
{
	srand(time(0));
	return (rand()%52 + 1);
}

BadDude::BadDude(const std::string & fr, const std::string & ls, 
	int nn, double dt) : Person(fr, ls), Gunslmger(fr, ls, nn, dt)
{
}

double BadDude::Gdraw()
{
	return Gunslmger::draw();
}

int BadDude::Cdraw()
{
	return PokerPlayer::draw();
}

void BadDude::show()
{
	Gunslmger::show();
}

/***********************************
	2017年12月8日11:04:32
	Athor:xiyuan255
	Course:C++
	Contain:useperson.cpp
			 person.h
		     person.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十四章的第四题练习题
		 【 参考 P598 】
*************************************/
// workmi.cpp -- multiple inheritance
// compile with workermi.cpp
#include <iostream>
#include <cstring>
#include "person.h"
 
const int SIZE = 4;

int main()
{
	using std::cin;
	using std::cout;
	using std::endl;
	using std::strchr;
	Person * lolas[SIZE];
	int ct;
	int nicknumber = 10;
	for (ct = 0; ct < SIZE; ct++) {
		char choice;
		cout << "[ Enter the employee category: ]\n"
				<< "g: Gunslmger p: PokerPlayer "
				<< "b: BadDude   q: quit\n";
		cin >> choice;
		/* 原型extern char * strchr(const char * s, char c)
			* 查找字符串s中首次出现字符c的位置,如不存在返回0 */
		while (strchr("gpbq", choice) == NULL) {
			cout << "Please enter a g, p, b, or q: ";
			cin >> choice;
		}
		if ('q' == choice)
			break;
		nicknumber += 5;
		switch (choice) {
			case 'g': lolas[ct] = new Gunslmger("Guns", "Lmger", nicknumber, 3); // 调用默认构造函数
				break;
			case 'p': lolas[ct] = new PokerPlayer("Poker", "Player"); // 调用默认构造函数
				break;
			case 'b': lolas[ct] = new BadDude("Bad", "Dude", nicknumber, 5); // 调用默认构造函数
				break;
		}
		cin.get(); // 获取‘\n’字符
	}
	cout << "\nHere is your staff:\n";
	int i;
	for (i = 0; i < ct; i++) {
		cout << endl;
		lolas[i]->show();
	}
	/* 该代码块执行完毕后,会释放局部变量的内存,即Person * lolas[SIZE]
		* 数组,担不会释放该数组元素的指针变量指向的对象内存,因为它们是用
		* new分配的,所以需要显式释放。*/
	for (i = 0; i < ct; i++) 
		delete lolas[i];

	BadDude * badd = new BadDude("Bad", "Dude", nicknumber, 12);
	cout << "拔枪时间:" << badd->Gdraw() << endl;
	cout << "下一张扑克牌:" << badd->Cdraw() << endl;
	delete badd;

	cout << "Bye.\n";

	return 0;
}

/**
输出结果:
	[ Enter the employee category: ]
	g: Gunslmger p: PokerPlayer b: BadDude   q: quit
	g
	[ Enter the employee category: ]
	g: Gunslmger p: PokerPlayer b: BadDude   q: quit
	p
	[ Enter the employee category: ]
	g: Gunslmger p: PokerPlayer b: BadDude   q: quit
	b
	[ Enter the employee category: ]
	g: Gunslmger p: PokerPlayer b: BadDude   q: quit
	q

	Here is your staff:

	FirstName: Guns
	LastName: Lmger
	NickNumber15
	DrawTime3

	FirstName: Poker
	LastName: Player

	FirstName: Bad
	LastName: Dude
	NickNumber25
	DrawTime5
	拔枪时间:12
	下一张扑克牌:8
	Bye.
*/

// emp.h -- header file for abstr_emp class and children
#ifndef __EMP_H__
#define __EMP_H__

#include <iostream>
#include <string>

class Abstr_Emp
{
private:
	std::string fname;   // abstr_emp's first name
	std::string lname;   // abstr_emp's last name
	std::string job;
public:
	Abstr_Emp();
	Abstr_Emp(const std::string & fn, const std::string & ln,
			const std::string & j);
	virtual void showAll() const;  // labels and ahows all data
	virtual void setAll();         // prompts user for values
	friend std::ostream & 
		operator<<(std::ostream & os, const Abstr_Emp & e);
	// just display first and last name
	virtual ~Abstr_Emp() = 0;      // virtual base class
};

class Employee : public Abstr_Emp
{
public:
	Employee();
	Employee(const std::string & fn, const std::string & ln,
			const std::string & j);
	virtual void showAll() const;
	virtual void setAll();
};

class Manager :virtual public Abstr_Emp 
{
private:
	int inchargeof;    // number of Abstr_Emp managed
protected:
	int inChargeOf() const { return inchargeof; }  // output
	int & inChargeOf() { return inchargeof; }      // input
public:
	Manager();
	Manager(const std::string & fn, const std::string & ln,
			const std::string & j, int ico = 0);
	Manager(const Abstr_Emp & e, int ico);
	Manager(const Manager & m);
	virtual void data() const;
	virtual void setData();
	virtual void showAll() const;
	virtual void setAll();
};

class Fink : virtual public Abstr_Emp
{
private:
	std::string reportsto;    // to whom fink reports
protected:
	const std::string reportsTo() const { return reportsto; }
	std::string & reportsTo() { return reportsto; }
public:
	Fink();
	Fink(const std::string & fn, const std::string & ln,
			const std::string & j, const std::string & rpo);
	Fink(const Abstr_Emp & e, const std::string & rpo);
	Fink(const Fink & f);
	virtual void data() const;
	virtual void setData();
	virtual void showAll() const;
	virtual void setAll();
};

class HighFink : public Manager, public Fink  // management fink
{
public:
	HighFink();
	HighFink(const std::string & fn, const std::string & ln,
			const std::string & j, const std::string & rpo,
			int ico);
	HighFink(const Abstr_Emp & e, const std::string & rpo, int ico);
	HighFink(const Fink & f, int ico);
	HighFink(const Manager & m, const std::string & rpo);
	HighFink(const HighFink & h);
	virtual void showAll() const;
	virtual void setAll();
};

#endif /* __EMP_H__ */

// emp.cpp -- class menthods definition
#include "emp.h"

// class Abstr_Emp methods
Abstr_Emp::Abstr_Emp()
{
	fname = "none";
	lname = "none";
	job = "none";
}

Abstr_Emp::Abstr_Emp(const std::string & fn, 
				const std::string & ln,
				const std::string & j)
{
	fname = fn;
	lname = ln;
	job = j;
}

Abstr_Emp::~Abstr_Emp()
{ }

void Abstr_Emp::showAll() const
{
	std::cout << "FirstName: " << fname << std::endl;
	std::cout << "LastName: " << lname << std::endl;
	std::cout << "JobName: " << job << std::endl;
}

void Abstr_Emp::setAll()
{
	std::cout << "Enter first name: ";
	getline(std::cin, fname);
	std::cout << "Enter last name: ";
	getline(std::cin, lname);
	std::cout << "Enter job name: ";
	getline(std::cin, job);
}

std::ostream & operator<<(std::ostream & os, const Abstr_Emp & e)
{
	os << e.fname << ", " << e.lname << ", " << e.job << " ";
	return os;
}

// class Employee methods
Employee::Employee() : Abstr_Emp()
{ }

Employee::Employee(const std::string & fn, 
	const std::string & ln, const std::string & j)
	: Abstr_Emp(fn, ln, j)
{ }

void Employee::showAll() const
{
	Abstr_Emp::showAll();
}

void Employee::setAll()
{
	Abstr_Emp::setAll();
}

// class Manager methods
Manager::Manager() : Abstr_Emp(), inchargeof(0)
{ }

Manager::Manager(const std::string & fn, 
	const std::string & ln, const std::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::data() const
{
	std::cout << "InChargeOf: " << inchargeof << std::endl;
}

void Manager::showAll() const
{
	Abstr_Emp::showAll();
	data();
}

void Manager::setData()
{
	std::cout << "Enter InChargeOf: ";
	std::cin >> inchargeof;
	while (std::cin.get() != '\n')
		continue;
}

void Manager::setAll()
{
	Abstr_Emp::setAll();
	setData();
}

// class Fink methods
Fink::Fink() : Abstr_Emp(), reportsto("none")
{ }

Fink::Fink(const std::string & fn, const std::string & ln,
		const std::string & j, const std::string & rpo)
		: Abstr_Emp(fn, ln, j), reportsto(rpo)
{
}

Fink::Fink(const Abstr_Emp & e, const std::string & rpo)
	: Abstr_Emp(e), reportsto(rpo)
{
}

Fink::Fink(const Fink & f) : Abstr_Emp(f)
{
	reportsto = f.reportsto;
}

void Fink::data() const
{
	std::cout << "ReportsTo: " << reportsto << std::endl;
}

void Fink::showAll() const
{
	Abstr_Emp::showAll();
	data();
}

void Fink::setData()
{
	std::cout << "Enter ReportsTo: ";
	getline(std::cin, reportsto);
}

void Fink::setAll()
{
	Abstr_Emp::setAll();
	setData();
}

// class Fink methods
HighFink::HighFink() : Abstr_Emp(), Manager(), Fink()
{ }

HighFink::HighFink(const std::string & fn, const std::string & ln,
			const std::string & j, const std::string & rpo,
			int ico) : Abstr_Emp(fn, ln, j), Fink(fn, ln, j, rpo),
			Manager(fn, ln, j, ico)
{ }

HighFink::HighFink(const Abstr_Emp & e, const std::string & rpo, 
	int ico) : Abstr_Emp(e), Fink(e, rpo)
{ }

HighFink::HighFink(const Fink & f, int ico) 
	: Abstr_Emp(f), Fink(f), Manager((f), ico)  // (Abstr_Emp &)
{ }

HighFink::HighFink(const Manager & m, const std::string & rpo)
	: Abstr_Emp(m), Manager(m), Fink(m, rpo)
{ }

HighFink::HighFink(const HighFink & h) : Abstr_Emp(h),
			Manager(h), Fink(h)
{ }

void HighFink::showAll() const
{
	Abstr_Emp::showAll();
	Manager::data();
	Fink::data();
}

void HighFink::setAll()
{
	Abstr_Emp::setAll();
	Manager::setData();
	Fink::setData();
}

/***********************************
	2017年12月8日14:51:22
	Athor:xiyuan255
	Course:C++
	Contain:pe14-5.cpp
			 emp.h
		     emp.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十四章的第五题练习题
		 【 参考 P598 】
*************************************/
// pe14-5.cpp 
// useemp1.cpp -- using the Abstr_Emp classes
#include <iostream>
using namespace std;
#include "emp.h"

int main( void )
{
	Employee em("Trip", "Harris", "Thumper");
	cout << em << endl;
	em.showAll();
	Manager ma("Amophia", "Spindragon", "Nuancer", 5);
	cout << ma << endl;
	ma.showAll();

	Fink fi("Matt", "Oggs", "Oiler", "Juno Barr");
	cout << fi << endl;
	fi.showAll();
	HighFink hf(ma, "Curly Kew");   // recruitment?
	hf.showAll();
	cout << "Press a key for next phase:\n";
	cin.get();
	HighFink hf2;
	hf2.setAll();

	cout << "Uisng an Abstr_Emp * pointer:\n";
	Abstr_Emp * tri[4] = { &em, &fi, &hf, &hf2 };
	for (int i = 0; i < 4; i++)
		tri[i]->showAll();

	return 0;
}

/**
输出结果:
	Trip, Harris, Thumper
	FirstName: Trip
	LastName: Harris
	JobName: Thumper
	Amophia, Spindragon, Nuancer
	FirstName: Amophia
	LastName: Spindragon
	JobName: Nuancer
	InChargeOf: 5
	Matt, Oggs, Oiler
	FirstName: Matt
	LastName: Oggs
	JobName: Oiler
	ReportsTo: Juno Barr
	FirstName: Amophia
	LastName: Spindragon
	JobName: Nuancer
	InChargeOf: 5
	ReportsTo: Curly Kew
	Press a key for next phase:

	Enter first name: zhang
	Enter last name: xiao ming
	Enter job name: programmer
	Enter InChargeOf: 1234
	Enter ReportsTo: Thanks!
	Uisng an Abstr_Emp * pointer:
	FirstName: Trip
	LastName: Harris
	JobName: Thumper
	FirstName: Matt
	LastName: Oggs
	JobName: Oiler
	ReportsTo: Juno Barr
	FirstName: Amophia
	LastName: Spindragon
	JobName: Nuancer
	InChargeOf: 5
	ReportsTo: Curly Kew
	FirstName: zhang
	LastName: xiao ming
	JobName: programmer
	InChargeOf: 1234
	ReportsTo: Thanks!
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值