C++ Primer Plus (第六版)编程练习记录(chapter14 C++中的代码重用)

本文通过C++ Primer Plus第六版的编程练习,探讨了类的设计与重用,包括Wine类的实现,私有继承的应用,模板QueueTp的创建,Person类及其派生类Gunslinger、PokerPlayer、BadDude的定义,以及一个类层次结构的实例。内容涵盖了虚基类、多重继承、保护方法、抽象类和虚函数的使用。

1.Wine类有一个string类对象成员(参见第4章)和一个Pair对象(参见本章);其中前者用于存储葡萄酒的名称,而后者有2个valarray对象(参见本章),这两个valarray对象分别保存了葡萄酒的酿造年份和该年生产的瓶数。例如,Pair的第1个valarray对象可能为1988、1992和1996年,第2个valarray对象可能为24、48和144瓶。Wine最好有1个int成员用于存储年数。另外,一些typedef可能有助于简化编程工作:

typedef std::valarry<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;

这样,PairArray表示的是类型Pair<std::valarray, std::valarray >。使用包含来实现Wine类,并用一个简单的程序对其进行测试。Wine类应该有一个默认构造函数以及如下构造函数:

Wine(const char* l, int y, const int yr[], const int bot[]);
Wine(const char* l, int y);

Wine类应该有一个GetBottles( )方法,它根据Wine对象能够存储几种年份(y),提示用户输入年份和瓶数。方法Label( )返回一个指向葡萄酒名称的引用。sum( )方法返回Pair对象中第二个valarray对象中的瓶数总和。
测试程序应提示用户输入葡萄酒名称、元素个数以及每个元素存储的年份和瓶数等信息。程序将使用这些数据来构造一个Wine对象,然后显示对象中保存的信息。
下面是一个简单的测试程序:

int main()
{
    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);
    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 bottle for " << more.Label()
    <<": " << more.sum() << endl;
    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 bottle for Gushing Grape  Red: 180
Bye
//clss.h
#ifndef CLASS_H_
#define CLASS_H_
#include <iostream>
#include <valarray>
#include <string>

class Wine
{
	typedef std::valarray<int> ArrayInt;
	typedef std::pair<ArrayInt, ArrayInt> PairArray;

public:
	Wine(const char* l, int y, const int yr[], const int bot[]);
	Wine(const char* l, int y);
	~Wine() {};

	void GetBottles();
	std::string& Label();
	int sum()const;
	void Show()const;

private:
	std::string label;
	PairArray info;
	int yearnum;
};


#endif // !CLASS_H_
//class.cpp
#include"class.h"

Wine::Wine(const char* l, int y, const int yr[], const int bot[])
{
	label = l;
	yearnum = y;
	info.first.resize(yearnum);
	info.second.resize(yearnum);
	for (int i = 0; i < y; i++)	
	{
		info.first[i] = yr[i];
		info.second[i] = bot[i];
	}
}

Wine::Wine(const char* l, int y)
{
	label = l;
	yearnum = y;
}

void Wine::GetBottles()
{
	using namespace std;
	cout << "Enter " << label << " data for " << yearnum << " year(s):\n";

	info.first.resize(yearnum);	//这一步非常重要,不重新设置长度的话会退出
	info.second.resize(yearnum);

	for (int i = 0;i < yearnum;i++)
	{
		cout << "Enter year: ";
		cin >> info.first[i];

		cout << "Enter bottles for that year: ";
		cin >> info.second[i];
	}
}

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

int Wine::sum() const
{
	return info.second.sum();
}

void Wine::Show() const
{
	using namespace std;
	cout << "Wine: " << label << endl;;
	cout << "\tYear\tBottles\n";
	for (int i = 0;i < yearnum;i++)
	{
		cout << '\t'<<info.first[i];
		cout << '\t' << info.second[i] << endl;
	}
}
//main.cpp
/* *************************************************
* 文件名:
* 创建人:px
* 创建时间:2020/5/6
* 描述:
************************************************* */
#include<iostream>
#include"class.h"
using namespace std;


int main()
{
	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);
	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 bottle for " << more.Label()
		<< ": " << more.sum() << endl;
	cout << "Bye\n";

	return 0;
}

2.采用私有继承而不是包含来完成编程练习1。同样,一些typedef可能会有所帮助,另外,您可能还需要考虑诸如下面这样的语句的含义:

PairArray::operator=(PairArray(ArrayInt(),ArrayInt()));
cout<<(const string& )(*this);

您设计的类应该可以使用编程练习1中的测试程序进行测试。

//clss.h
#ifndef CLASS_H_
#define CLASS_H_
#include <iostream>
#include <valarray>
#include <string>

typedef std::valarray<int> ArrayInt;
typedef std::pair<ArrayInt, ArrayInt> PairArray;

class Wine :private std::string, private PairArray
{
public:
	Wine(const char* l, int y, const int yr[], const int bot[]);
	Wine(const char* l, int y);
	~Wine() {};

	void GetBottles();
	std::string Label();
	int sum()const;
	void Show()const;

private:
	int yearnum;
};

#endif // !CLASS_H_
//class.cpp
#include"class.h"

Wine::Wine(const char* l, int y, const int yr[], const int bot[]):std::string(l),yearnum(y),PairArray(ArrayInt(yr,y), ArrayInt(bot, y))
{
}

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

void Wine::GetBottles()
{
	using namespace std;
	cout << "Enter " <<std::string::c_str()<< " data for " << yearnum << " year(s):\n";
	
	PairArray::first.resize(yearnum);
	PairArray::second.resize(yearnum);
	
	for (int i = 0;i < yearnum;i++)
	{
		cout << "Enter year: ";
		cin >> PairArray::first[i];

		cout << "Enter bottles for that year: ";
		cin >> PairArray::second[i];
	}
}

std::string Wine::Label()
{
	std::string st = std::string::c_str();
	return st;
}

int Wine::sum() const
{
	return PairArray::second.sum();
}

void Wine::Show() const
{
	using namespace std;
	cout << "Wine: " << std::string::c_str() << endl;;
	cout << "\tYear\tBottles\n";
	for (int i = 0;i < yearnum;i++)
	{
		cout << '\t'<<PairArray::first[i];
		cout << '\t' << PairArray::second[i] << endl;
	}
}

3.定义一个QueueTp模板。然后在一个类似于程序清单14.12的程序中创建一个指向Worker的指针队列(参见程序清单12.10中的定义),并使用该队列来测试它。

//clss.h
#ifndef CLASS_H_
#define CLASS_H_
#include <iostream>
#include <valarray>
#include <string>

class Worker
{
public:
	Worker() :fullname("no one"), id(0L) {};
	Worker(const std::string& s, long n) :fullname(s), id(n) {};
	~Worker() ;
	void Set(const char* name, long id);
	void Show()const ;

private:
	std::string fullname;
	long id;
protected:
	virtual void Data()const;
	virtual void Get();
};

template<typename T>
class QueueTp
{
public:
	QueueTp(int qs = Q_SIZE);
	~QueueTp();
	bool isempty()const;
	bool isfull()const;
	int quequecount()const;
	bool enqueue(const T& item);
	bool dequeue(T& item);
private:
	struct Node 
	{ 
		T item;
		struct 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<typename T>
QueueTp<T>::QueueTp(int qs) :qsize(qs)
{
}

template<typename T>
QueueTp<T>::~QueueTp()
{
	Node* temp;
	while (front != NULL)
	{
		temp = front;
		front = front->next;
		delete temp;
	}
}

template<typename T>
bool QueueTp<T>::isempty() const
{
	return items == 0;
}

template<typename T>
bool QueueTp<T>::isfull() const
{
	return items == qsize;
}

template<typename T>
int QueueTp<T>::quequecount() const
{
	return items;
}

template<typename T>
bool QueueTp<T>::enqueue(const T& item)
{
	if (isfull())
		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<typename T>
bool QueueTp<T>::dequeue(T& item)
{
	if (front == NULL)
		return false;
	item = front->item;
	items--;
	Node* detemp = front;
	front = front->next;
	delete detemp;
	if (items == 0)
		rear = NULL;
	return true;
}

#endif // !CLASS_H_
//class.cpp
#include"class.h"
#include <string>
Worker::~Worker()
{
}
void Worker::Set(const char* name, long num)
{
	fullname = name;
	id = num;
}
void Worker::Show() const
{
	using std::cout;
	using std::endl;
	cout << "Name: " << fullname << endl;
	cout << "ID: " << id << endl;
}
void Worker::Data() const
{
	std::cout << "Name: " << fullname << std::endl;
	std::cout << "Employee ID: " << id << std::endl;
}

void Worker::Get()
{
	using std::cout;
	using std::cin;
	getline(cin, fullname);
	cout << "Enter worker's ID: ";
	cin >> id;
	while (cin.get() != '\n')
		continue;
}
//main.cpp
/* *************************************************
* 文件名:
* 创建人:px
* 创建时间:2020/5/6
* 描述:
************************************************* */
#include<iostream>
#include<string>
#include"class.h"


int main()
{
	using namespace std;
	QueueTp<Worker> workerque;
	
	Worker w1("Tom", 10000);
	Worker w2("Mike", 10001);
	workerque.enqueue(w1);
	workerque.enqueue(w2);

	Worker temp;
	workerque.dequeue(temp);
	temp.Show();
	cout << "Bye.\n";
	return 0;
}

4.Person类保存人的名和姓。除构造函数外,它还有Show( )方法,用于显示名和姓。Gunslinger类以Person类为虚基类派生而来,它包含一个Draw( )成员,该方法返回一个double值,表示枪手的拔枪时间。这个类还包含一个int成员,表示枪手枪上的刻痕数。最后,这个类还包含一个Show( )函数,用于显示所有这些信息。
PokerPlayer类以Person类为虚基类派生而来。它包含一个Draw( )成员,该函数返回一个1~52的随机数,用于表示扑克牌的值(也可以定义一个Card类,其中包含花色和面值成员,然后让Draw( )返回一个Card对象)。PokerPlayer类使用Person类的show( )函数。BadDude( )类从Gunslinger和PokerPlayer类公有派生而来。它包含Gdraw( )成员(返回坏蛋拔枪的时间)和Cdraw( )成员(返回下一张扑克牌),另外还有一个合适的Show( )函数。
请定义这些类和方法以及其他必要的方法(如用于设置对象值的方法),并使用一个类似于程序清单14.12的简单程序对它们进行测试。

//class.h
#ifndef CLASS_H_
#define CLASS_H_
#include <iostream>
#include <string>
using namespace std;
class Person
{
public:
	Person(const string fn="none", const string ln="\0");
	virtual ~Person() {};
	void Data()const;
	virtual void Show()const;

private:
	std::string firstname;
	std::string lastname;

};

class Gunslinger: virtual public Person
{
public:
	Gunslinger(const string fn = "none", const string ln = "\0", int n = 0, double t = 0.0);
	~Gunslinger() {};
	void Data()const;
	double Draw();
	void Show()const;
private:
	int notches;
	double time;
};

class PokePlayer:virtual public Person
{
public:
	PokePlayer(const string fn = "none", const string ln = "\0");
	~PokePlayer() {};
	void Data()const;
	int Draw();
private:
	int pokenum;
};
class BadDude:public Gunslinger,public PokePlayer
{
public:
	BadDude(const string fn = "none", const string ln = "\0", int n = 0, double t = 0.0);
	~BadDude() {};
	double Gdraw();
	int Cdraw();
	void Show()const;
};

#endif // !CLASS_H_
//class.cpp
#include"class.h"

Person::Person(const string fn, const string ln)
{
	firstname = fn;
	lastname = ln;
}

void Person::Show() const
{
	Data();
}

void Person::Data() const
{
	std::cout << "Full name: " << firstname << " " << lastname << '\n';
}

Gunslinger::Gunslinger(const string fn, const string ln, int n,double t):Person(fn,ln),notches(n),time(t)
{
}

void Gunslinger::Data() const
{
	std::cout << "Notch(es): " << notches << std::endl;
}

double Gunslinger::Draw()
{
	return time;
}

void Gunslinger::Show() const
{
	Person::Data();
	Data();
}

PokePlayer::PokePlayer(const string fn, const string ln):Person(fn,ln)
{
	pokenum = rand() % 52;
}

void PokePlayer::Data() const
{
	std::cout << "Poke Number: " << pokenum << std::endl;
}

int PokePlayer::Draw()
{
	return pokenum;
}

BadDude::BadDude(const string fn, const string ln, int n, double t):Person(fn,ln),Gunslinger(fn,ln,n,t),PokePlayer(fn,ln)
{
}

double BadDude::Gdraw()
{
	int temp=Gunslinger::Draw();
	return temp;
}

int BadDude::Cdraw()
{
	double temp = PokePlayer::Draw();
	return temp;
}

void BadDude::Show() const
{
	Person::Data();
	Gunslinger::Data();
	PokePlayer::Data();
}
//main.cpp
/* *************************************************
* 文件名:
* 创建人:px
* 创建时间:2020/5/6
* 描述:
************************************************* */
#include<iostream>
#include<string>
#include"class.h"


int main()
{
	using namespace std;
	const int SIZE = 3;

	Person* p[SIZE];
	int n;
	double t;
	for (int i = 0; i < SIZE; i++)
	{
		char flag;
		cout << "Enter the person category:\n" << "g: Gunslinger  p: PokerPlayer  b: BadDude  q: Quit\n";
		cin >> flag;
		
	
		while (strchr("gpbq", flag) == NULL)
		{
			cout << "Please enter a g, p, b, or q: ";
			cin >> flag;
		}
		if (flag == 'q')
		{
			break;
		}
		cin.get();	//清除换行符
		string fname;
		string lname;
		
		cout << "Please enter the first name: ";
		getline(cin, fname);
		
		cout << "Please enter the last name: ";
		getline(cin, lname);
		
		switch (flag)
		{
		case 'g':
			cout << "Enter notch(es): ";
			cin >> n;
			cout << "Enter time of gun: ";
			cin >> t;
			p[i] = new Gunslinger(fname, lname, n, t);
			break;
		case 'p':
			p[i] = new PokePlayer(fname, lname);
			break;
		case 'b':
			cout << "Enter notch(es): ";
			cin >> n;
			cout << "Enter time of gun: ";
			cin >> t;
			p[i] = new BadDude(fname, lname, n, t);
			break;
		}
	}
	cout << "\nHere is your person:\n";

	for (int i = 0; i < SIZE; i++)
	{
		cout << endl;
		p[i]->Show();
	}
	for (int i = 0; i < SIZE; i++)
		delete p[i];
	cout << "Bye\n";
	system("pause");
	return 0;
}

5.下面是一些类声明:

#include <iostream>
#include <string>
class AbstrEmp
{
private:
	string _fname;
	string _lname;
	string _job;
public:
	AbstrEmp();
	AbstrEmp(const std::string& fn, const string& ln, const string& j);
	virtual void showAll()const;
	virtual void setAll();
	friend ostream& operator<<(ostream& os, const AbstrEmp& e);
	virtual ~AbstrEmp() = 0;
};
class Employee : public AbstrEmp
{
public:
	Employee();
	Employee(const string& fn, const string& ln, const string& j);
	virtual void showAll()const;
	virtual void setAll();
};
 
class Manager : virtual public AbstrEmp
{
private:
	int _inchargeof;
protected:
	int inChargeOf()const
	{
		return _inchargeof;
	}
	int& inChargeOf()
	{
		return _inchargeof;
	}
public:
	Manager();
	Manager(const string& fn, const string& ln, const string& j0, int ico = 0);
	Manager(const AbstrEmp& e, int ico);
	Manager(const Manager& m);
	virtual void showAll()const;
	virtual void setAll();
};
 
class Fink : virtual public AbstrEmp
{
private:
	string _reportsto;
protected:
	const string reportsTo() const{ return _reportsto; }
	string& reportsTo(){ return _reportsto; }
public:
	Fink();
	Fink(const string& fn, const string& ln, const string& j, const string& rpo);
	Fink(const AbstrEmp& e, const string& rpo);
	Fink(const Fink& e);
	virtual void showAll()const;
	virtual void setAll();
};
 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 AbstrEmp& e, const string& rpo, int ico);
	HighFink(const Fink& f, int ico);
	HighFink(const Manager& m, const string& rpo);
	HighFink(const HighFink& h);
	virtual void showAll()const;
	virtual void setAll();
};

注意,该类层次结构使用了带虚基类的MI,所以要牢记这种情况下用于构造函数初始化列表的特殊规则。还需要注意的是,有些方法被声明为保护的。这可以简化一些highfink方法的代码(例如,如果highfink::ShowAll( )只是调用fink::ShowAll( )和manager::ShwAll(),则它将调用abstr_emp::ShowAll( )两次)。请提供类方法的实现,并在一个程序中对这些类进行测试。下面是一个小型测试程序:

#include <iostream>     
using namespace std;
#include "emp.h"

int main(void)
{
	Employee em("Trip", "Harris", "Thumper");
	cout << em << endl;
	em.showAll();
	Manager ma("Amorphia", "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");
	hf.showAll();
	cout << "Press a key for next phase:\n";
	cin.get();
	HighFink hf2;
	hf2.setAll();
 
	cout << "Using an abstr_emp * pointer:\n";
	AbstrEmp* tri[4] = { &em, &fi, &hf, &hf2 };
	for (int i = 0; i < 4; ++i)
	{
		tri[i]->showAll();
	}
	return 0;
}

为什么没有定义赋值运算符?
因为不涉及动态内存分配,使用默认的赋值运算符即可。

为什么要将ShowAll( )和SetAll( )定义为虚的?
因为这样在使用基类指针来指向各个类,并调用showAll()和setAll()方法时会根据所指向变量的实际类型来调用对应的方法。

为什么要将abstr_emp定义为虚基类?
因为这里没有设置为abstr_emp的变量,虚基类可以只包括一些抽象函数的声明,而不给出其具体实现。

为什么highfink类没有数据部分?
因为它具有abstr_emp、manager、fink这三个类的副本,所有继承得来的数据有fname、lname、job、inchargeof、reportsto。

为什么只需要一个operator<<( )版本?
这个运算符重载是在虚基类里完成的,之后所继承的派生类都会继承这个函数。

如果使用下面的代码替换程序的结尾部分,将会发生什么情况?

abstr_emp tri[4] = {em, fi, hf, hf2};
for(int i = 0; i < 4; ++i)
    tri[i].showAll()

会报错,因为abstr_emp是虚基类,不能创建对象。

//class.h
#ifndef CLASS_H_
#define CLASS_H_
#include <iostream>
#include <string>
using namespace std;

class AbstrEmp
{
private:
	string fname;
	string lname;
	string job;
public:
	AbstrEmp();
	AbstrEmp(const std::string& fn, const string& ln, const string& j) :fname(fn), lname(ln), job(j) {};
	virtual void showAll()const;
	virtual void setAll();
	friend ostream& operator<<(ostream& os, const AbstrEmp& e);
	virtual ~AbstrEmp() = 0;
};
class Employee : public AbstrEmp
{
public:
	Employee() :AbstrEmp() {}
	Employee(const string& fn, const string& ln, const string& j) :AbstrEmp(fn, ln, j) {}
	virtual void showAll()const { AbstrEmp::showAll(); }
	virtual void setAll() { AbstrEmp::setAll(); }
};

class Manager : virtual public AbstrEmp
{
private:
	int inchargeof;
protected:
	int inChargeOf()const { return inchargeof; }
	int& inChargeOf() { return inchargeof; }
public:
	Manager() :AbstrEmp(),inchargeof(0){}
	Manager(const string& fn, const string& ln, const string& j0, int ico = 0) 
		:AbstrEmp(fn, ln, j0), inchargeof(ico) {}
	Manager(const AbstrEmp& e, int ico) :AbstrEmp(e), inchargeof(ico) {} 
	Manager(const Manager& m) :AbstrEmp(m) { inchargeof = m.inchargeof; }
	
	virtual void showAll()const;
	virtual void setAll();
	

};

class Fink : virtual public AbstrEmp
{
private:
	string reportsto;
protected:
	const string reportsTo() const { return reportsto; }
	string& reportsTo() { return reportsto; }
public:
	Fink() :AbstrEmp() {}
	Fink(const string& fn, const string& ln, const string& j, const string& rpo) :AbstrEmp(fn, ln, j), reportsto(rpo) {}
	Fink(const AbstrEmp& e, const string& rpo) :AbstrEmp(e), reportsto(rpo) {}
	Fink(const Fink& e) :AbstrEmp(e) {}
	
	virtual void showAll()const;
	virtual void setAll();
};
class HighFink : public Manager, public Fink
{
public:
	HighFink() :AbstrEmp(), Manager(), Fink() {}
	HighFink(const string& fn, const string& ln, const string& j, const string& rpo, int ico) 
		:AbstrEmp(fn, ln, j), Manager(fn, ln, j, ico), Fink(fn, ln, j, rpo) {}
	HighFink(const AbstrEmp& e, const string& rpo, int ico)
		:AbstrEmp(e), Manager(e, ico), Fink(e, rpo) {}
	HighFink(const Fink& f, int ico) :AbstrEmp(f), Fink(f),Manager(f,ico) {}	
	//Manager(f,ico)将f回传给AbstrEmp(),但会被虚继承的机制阻断,这样写只是利用Manager(f,ico)重设了ico
	HighFink(const Manager& m, const string& rpo) :AbstrEmp(m), Manager(m), Fink(m, rpo) {}	
	HighFink(const HighFink& h) :AbstrEmp(h), Manager(h), Fink(h) {}

	virtual void showAll()const;
	virtual void setAll();
};
#endif // !CLASS_H_
//class.cpp
#include"class.h"

AbstrEmp::AbstrEmp()
{
	fname = "None";
	lname = '\0';
	job = "None";
}

void AbstrEmp::showAll() const
{
	cout << endl;
	cout << "Name: " << fname << " " << lname << endl;
	cout << "Job:" << job << endl;
}

void AbstrEmp::setAll()
{
	cin.get();							//清除上一个cin留下的换行符
	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 AbstrEmp& e)
{
	os << std::endl;
	os << e.fname << " " << e.lname;
	return os;
}
AbstrEmp:: ~AbstrEmp()
{
}


void Manager::showAll() const
{
	AbstrEmp::showAll();
	cout << "Inchargeof: " << inchargeof << endl;
}

void Manager::setAll()
{
	AbstrEmp::setAll();
	cout << "Enter inchargeof: ";
	cin >> inChargeOf();
}

void Fink::showAll() const
{
	AbstrEmp::showAll();
	cout << "Reperts to: " << reportsto << endl;
}

void Fink::setAll()
{
	AbstrEmp::setAll();
	cin.get();
	cout << "Enter reportsto: ";
	getline(cin, reportsTo());
	

}

void HighFink::showAll() const
{
	AbstrEmp::showAll();
	cout << "Inchargeof: "<< Manager::inChargeOf() << endl;
	cout << "Reportsto: " << Fink::reportsTo() << endl;
}

void HighFink::setAll()
{
	AbstrEmp::setAll();
	cout << "Enter number of in-charge-of: ";
	cin >> Manager::inChargeOf();
	cin.get();
	cout << "Enter name reports to: ";
	getline(cin, Fink::reportsTo());
}
//main.cpp
/* *************************************************
* 文件名:
* 创建人:px
* 创建时间:2020/5/8
* 描述:
************************************************* */
#include<iostream>
#include<string>
#include"class.h"


int main(void)
{
	Employee em("Trip", "Harris", "Thumper");
	cout << em << endl;
	em.showAll();
	Manager ma("Amorphia", "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");
	hf.showAll();
	cout << "Press a key for next phase:\n";
	cin.get();

	HighFink hf2;
	hf2.setAll();

	cout << "Using an abstr_emp * pointer:\n";
	AbstrEmp* tri[4] = { &em, &fi, &hf, &hf2 };
	for (int i = 0; i < 4; ++i)
	{
		tri[i]->showAll();
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值