C++ Primer Plus章节编程练习第十四章
1
题目
Wine类有一个string类对象成员(参见第4章)和一个Pair对象(参见本章):其中前者用于存储葡萄酒的名称,而后者有2个valarray
typedef std::Valarry<int> ArrayInt;
typedef Pair<ArrayInt,ArryInt> PairArray;
这样,PairAray表示的是类型Par<std:valarray
// initialize label to 1,number of years to y,
// vintage years to yrl], bottles to bot l]
Wine(const char * l, int y, const int yr[],const int bot[]) ;
// initialize label to 1, number of years to y,
// create array objects of length y
Wine (const char * l, int y) ;
Wine类应该有一个Getottles()方法,它根据Wine对象能够存储几种年份(y), 提示用户输入年份和瓶数。方法Label()返回一个指向葡萄酒名称的引用。sum()方法返回Pair对象中第二个valarray
测试程序应提示用户输入葡萄酒名称、元素个数以及每个元素存储的年份和瓶数等信息。程序将使用这些数据来构造一个Wine对象,然后显示对象中保存的信息。下面是一个简单的测试程序:
int main(void){
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 bottles 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
Years Bottles
1988 42
1994 58
1998 122
2001 144
Wine: Gushing Grape Red
Years Bottles
1993 48
1995 60
1998 72
Total bottles for Gushing Grape Red: 180
Bye
题解
#include<iostream>
#include<string>
#include<valarray>
using namespace std;
//*******************Pairs模板类声明和定义如下*******************
template<class T1,class T2>
class Pair{
private:
T1 a;
T2 b;
public:
T1 &first(); //返回引用类型
T2 &second();
T1 first()const{return a;}
T2 second()const{return b;}
Pair(const T1& aval,const T2 &bval):a(aval),b(bval){}
Pair(){}
};
template<class T1,class T2>
T1& Pair<T1,T2>::first(){
return a;
}
template<class T1,class T2>
T2& Pair<T1,T2>::second(){
return b;
}
//*******************Pairs模板类声明和定义如下*******************
class Wine{
private:
typedef std::valarray<int> ArrayInt;
typedef Pair<ArrayInt,ArrayInt> PairArray;
string label;
int years_cnt;
PairArray years_bottles;
public:
Wine(){}
Wine(const char* l,int y,const int yr[],const int bot[]):
label(l),years_cnt(y),years_bottles(ArrayInt(yr,y),ArrayInt(bot,y)){}
Wine(const char* l,int y):
label(l),years_cnt(y),years_bottles(ArrayInt(y),ArrayInt(y)){}
~Wine(){}
void GetBottles();
string &Label(){return label;};
int sum(){return years_bottles.second().sum();}
void Show()const;
};
void Wine::GetBottles(){
cout<<"Enter "<<label<<" data for "<<years_cnt<<" year(s):\n";
for(int i=0;i<years_cnt;++i){
cout<<"Enter year: ";
cin>>years_bottles.first()[i];
cout<<"Enter bottles for that year: ";
cin>>years_bottles.second()[i];
}
}
void Wine::Show()const{
cout<<"Wine: "<<label<<endl;
cout<<"\tYears\tBottles"<<endl;
for(int i=0;i<years_cnt;++i){
cout<<"\t"<<years_bottles.first()[i]<<"\t"<<years_bottles.second()[i]<<endl;
}
}
int main(void){
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 bottles for "<<more.Label()
<<": "<<more.sum()<<endl;
cout<<"Bye\n";
return 0;
}
2
题目
采用私有继承而不是包含来完成编程练习1。同样,一些typedef可能会有所帮助,另外,您可能还需要考虑诸如下面这样的语句的含义:
PairArray::operator=(PairArray(ArrayInt(),ArryInt()));
cout<<(const string& )(*this);
您设计的类应该可以使用编程练习1中的测试程序进行测试。
题解
#include<iostream>
#include<string>
#include<valarray>
using namespace std;
//*******************Pairs模板类声明和定义如下*******************
template<class T1,class T2>
class Pair{
private:
T1 a;
T2 b;
public:
T1 &first(); //返回引用类型
T2 &second();
T1 first()const{return a;}
T2 second()const{return b;}
Pair(const T1& aval,const T2 &bval):a(aval),b(bval){}
Pair(){}
};
template<class T1,class T2>
T1& Pair<T1,T2>::first(){
return a;
}
template<class T1,class T2>
T2& Pair<T1,T2>::second(){
return b;
}
//*******************Pairs模板类声明和定义如下*******************
typedef std::valarray<int> ArrayInt;
typedef Pair<ArrayInt,ArrayInt> PairArray;
class Wine:private string,private PairArray{
private:
int years_cnt;
public:
Wine(){}
Wine(const char* l,int y,const int yr[],const int bot[]):
string(l),PairArray(ArrayInt(yr,y),ArrayInt(bot,y)),years_cnt(y){}
Wine(const char* l,int y):
string(l),PairArray(ArrayInt(y),ArrayInt(y)),years_cnt(y){}
~Wine(){}
void GetBottles();
string &Label(){return (string&)(*this);};
int sum(){return PairArray(*this).second().sum();}
void Show()const;
};
void Wine::GetBottles(){
cout<<"Enter "<<(const string&)(*this)<<" data for "<<years_cnt<<" year(s):\n";
for(int i=0;i<years_cnt;++i){
cout<<"Enter year: ";
cin>>((PairArray&)(*this)).first()[i]; //先转为PairArry的引用,再调用方法,注意括号优先级
cout<<"Enter bottles for that year: ";
cin>>((PairArray&)(*this)).second()[i];
}
}
void Wine::Show()const{
cout<<"Wine: "<<(const string&)(*this)<<endl;
cout<<"\tYears\tBottles"<<endl;
for(int i=0;i<years_cnt;++i){
cout<<"\t"<<PairArray(*this).first()[i]<<"\t"<<PairArray(*this).second()[i]<<endl;
}
}
int main(void){
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 bottles for "<<more.Label()
<<": "<<more.sum()<<endl;
cout<<"Bye\n";
return 0;
}
3
题目
定义一个QueueTp模板。然后在一一个类似于程序清单14.12 的程序中创建一个指向Worker的指针队列(参见程序清单14.10 中的定义),并使用该队列来测试它。
题解
//583 14.12 617
#include<iostream>
#include<string>
#include<cstring>
//需要使用的Worker类的相关声明和定义
//****************第一代: 基类Worker的声明****************
class Worker{
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;
virtual void Set()=0;
virtual void Show()const=0;
};
//****************第一代: 基类Worker的实现****************
Worker::~Worker(){}
void Worker::Data()const{
std::cout<<"Name: "<<fullname<<"\n";
std::cout<<"Employee ID: "<<id<<"\n";
}
void Worker::Get(){
std::getline(std::cin,fullname);
std::cout<<"Enter worker's ID: ";
std::cin>>id;
while(std::cin.get()!='\n')
continue;
}
//****************第二代: 派生类Waiter的声明****************
class Waiter:virtual public 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;
};
//****************第二代: 派生类Waiter的定义****************
void Waiter::Data()const{
std::cout<<"Panache rating: "<<panache<<"\n";
}
void Waiter::Get(){
std::cout<<"Enter waiter's panache rating: ";
std::cin>>panache;
while(std::cin.get()!='\n')
continue;
}
void Waiter::Set(){
std::cout<<"Enter waiter's name: ";
Worker::Get();
Get();
}
void Waiter::Show()const{
std::cout<<"Category: waiter\n";
Worker::Data();
Data();
}
//****************第二代: 派生类Singer的声明****************
class Singer:virtual public Worker{
protected:
enum{other,alto,contralto,soprano,bass,baritone,tenor};
enum{Vtypes=7};
void Data()const;
void Get();
private:
static char*pv[Vtypes];
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;
};
//****************第二代: 派生类Singer的定义****************
char* Singer::pv[]={"other","alto","contralto","soprano","bass","baritone","tenor"};
void Singer::Data()const{
std::cout<<"Vocal range: "<<pv[voice]<<std::endl;
}
void Singer::Get(){
std::cout<<"Enter number for singer's vocal range:\n";
int i;
for(i=0;i<Vtypes;++i){
std::cout<<i<<": "<<pv[i]<<" ";
if(i%4==3)
std::cout<<std::endl;
}
if(i%4!=0)
std::cout<<std::endl;
while(std::cin>>voice&&(voice<0||voice>=Vtypes))
std::cout<<"Please enter a value >= 0 and < "<<Vtypes<<std::endl;
while(std::cin.get()!='\n')
continue;
}
void Singer::Set(){
std::cout<<"Enter singer's name: ";
Worker::Get();
Get();
}
void Singer::Show()const{
std::cout<<"Category: singer\n";
Worker::Data();
Data();
}
//****************第三代: 多重继承派生类SingingWaiter的声明****************
class SingingWaiter: public Singer,public Waiter{
protected:
void Data()const;
void Get();
public:
SingingWaiter(){}
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&ws,int p=0):
Worker(ws),Waiter(ws,p),Singer(ws){}
void Set();
void Show()const;
};
//****************第三代: 多重继承派生类SingingWaiter的定义****************
//把基类的功能模块化,然后在派生类中调用,这样可以防止交叉调用
void SingingWaiter::Data()const{
Singer::Data();
Waiter::Data();
}
void SingingWaiter::Get(){
Waiter::Get();
Singer::Get();
}
void SingingWaiter::Set(){
std::cout<<"Enter singing waiter's name: ";
Worker::Get();
Get();
}
void SingingWaiter::Show()const{
std::cout<<"Catraget: singing waiter\n";
Worker::Data();
Data();
}
//****************QueeTP模板类的声明和定义****************
template<class T>
class QueeTP{
private:
int Max_size,front,rear;
T* queue;
public:
QueeTP(int size=20){ //size为容量,Max_size为实际使用的空间个数,要比最大的大一个
Max_size=size+1;
queue=new T[Max_size];
front=rear=0; //初始化
}
~QueeTP(){delete[] queue;}
int size(){ //计算大小
return (rear+Max_size)%Max_size-front;
}
bool isempty(){ //判空
return front==rear;
}
bool isfull(){
return size()==Max_size-1; //判满
}
bool push(const T &item){ //入队
if(isfull()) return false;
queue[rear++]=item;
rear%=Max_size;
return true;
}
bool pop(T &item){ //出队
if(isempty()) return false;
item=queue[front++];
front%=Max_size;
return true;
}
};
//********************测试函数********************
const int SIZE=5;
int main(){
using namespace std;
QueeTP<Worker*> q;
int ct;
for(ct=0;ct<SIZE;++ct){
char choice;
cout<<"Enter the employee category:\n"
<<"w: waiter s: singer "
<<"t: singing waitre 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;
while(cin.get()!='\n') continue;
Worker* wp;
switch(choice){
case 'w': wp=new Waiter;wp->Set();
if(q.isfull())
cout<<"queue is full!"<<endl;
else
q.push(wp);break;
case 's': wp=new Singer;wp->Set();
if(q.isfull())
cout<<"queue is full!"<<endl;
else
q.push(wp);break;
case 't': wp=new SingingWaiter;wp->Set();
if(q.isfull())
cout<<"queue is full!"<<endl;
else
q.push(wp);break;
}
}
while(!q.isempty()){
Worker* temp;
q.pop(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的简单程序对它们进行测试。
题解
#include<iostream>
#include<string>
#include<cstdlib>
#include<ctime>
using namespace std;
//*****************虚基类Person的定义和实现*****************
class Person{
private:
string firstname;
string lastname;
public:
Person(){}
Person(string fn,string ln):firstname(fn),lastname(ln){}
Person(const char* fn,const char* ln):firstname(fn),lastname(ln){}
Person(const Person& p):firstname(p.firstname),lastname(p.lastname){}
virtual ~Person(){}
virtual void Show()const=0;
};
void Person::Show()const{
cout<<firstname<<", "<<lastname;
}
//*****************派生类Gunslinger的定义和实现*****************
class Gunslinger:virtual public Person{
private:
double draw;
int score;
public:
Gunslinger(){}
Gunslinger(string fn,string ln,double dr,int sc):
Person(fn,ln),draw(dr),score(sc){}
Gunslinger(const char* fn,const char* ln,double dr,int sc):
Person(fn,ln),draw(dr),score(sc){}
Gunslinger(const Gunslinger& gl):Person(gl),draw(gl.draw),score(gl.score){}
virtual ~Gunslinger(){}
virtual double Draw()const{return draw;}
virtual void Show()const;
};
void Gunslinger::Show()const{
Person::Show();
cout<<endl;
cout<<"Draw time: "<<draw<<endl;
cout<<"Score: "<<score<<endl;
}
//*****************派生类PokerPlayer的定义和实现*****************
class PokerPlayer:virtual public Person{
public:
PokerPlayer(){}
PokerPlayer(string fn,string ln):Person(fn,ln){}
PokerPlayer(const char* fn,const char* ln):Person(fn,ln){}
virtual ~PokerPlayer(){}
virtual void Show()const;
virtual double Draw()const;
};
void PokerPlayer::Show()const{
Person::Show();
}
double PokerPlayer::Draw()const{
srand(time(0));
return rand()%52+1;
}
//*****************多重派生类BadDude的定义和实现*****************
class BadDude:public Gunslinger,public PokerPlayer{
public:
BadDude(){}
BadDude(string fn,string ln,double dr,int sc):
Person(fn,ln),Gunslinger(fn,ln,dr,sc){}
BadDude(const char* fn,const char* ln,double dr,int sc):
Person(fn,ln),Gunslinger(fn,ln,dr,sc){}
BadDude(const Gunslinger& gp):
Person(gp),Gunslinger(gp){}
virtual ~BadDude(){}
virtual void Show()const;
double Gdraw();
int Cdraw();
};
void BadDude::Show()const{
Gunslinger::Show();
}
double BadDude::Gdraw(){
return Gunslinger::Draw();
}
int BadDude::Cdraw(){
return PokerPlayer::Draw();
}
int main(){
const int SIZE=3;
Person* people[SIZE];
for(int i=0;i<3;i++){
string fn,ln;
double dr;
int sc;
cout<<"Please enter the firstname: ";
cin>>fn;
cout<<"Please enter the lastname: ";
cin>>ln;
switch(i){
case 0:{
cout<<"Please enter the draw time of the Gunslinger: ";
cin>>dr;
cout<<"Please enter the score of the Gunslinger: ";
cin>>sc;
people[i]=new Gunslinger(fn,ln,dr,sc);
break;
}
case 1:{
people[i]=new PokerPlayer(fn,ln);
break;
}
case 2:{
cout<<"Please enter the draw time of the BadDude: ";
cin>>dr;
cout<<"Please enter the score of the BadDude: ";
cin>>sc;
people[i]=new BadDude(fn,ln,dr,sc);
break;
}
}
}
for(int i=0;i<SIZE;++i){
people[i]->Show();
cout<<endl;
delete people[i];
}
Gunslinger gl("Bob","Smith",100,100);
PokerPlayer pp("Ray","Mack");
BadDude bd("Genji","Lucy",200,200);
cout<<gl.Draw()<<endl;
cout<<pp.Draw()<<endl;
cout<<bd.Gdraw()<<endl;
cout<<bd.Cdraw()<<endl;
return 0;
}
5
题目
下面是一些类声明:
#include<iostream>
#include<string>
class abstr_emp{
private:
string fname;
string lname;
string job;
public:
abstr_emp(){};
abstr_emp(const 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 abstr_emp &e);
virtual ~abstr_emp()=0;
};
class employee:public abstr_emp{
public:
employee();
employee(const string &fn,const string &ln,const string &j):abstr_emp(fn,ln,j){}
virtual void ShowAll()const;
virtual void SetAll();
};
class manager:virtual public abstr_emp{
private:
int inchargeof;
protected:
int InChargeof()const{return inchargeof;}
int &InChargeof(){return inchargeof;}
public:
manager(){};
manager(const string &fn,const string &ln,const string &j,int ico=0):
abstr_emp(fn,ln,j),inchargeof(ico){}
manager(const abstr_emp& e,int ico):
abstr_emp(e),inchargeof(ico){}
manager(const manager& m):
abstr_emp(m),inchargeof(m.inchargeof){}
virtual void ShowAll()const;
virtual void SetAll();
};
class fink: virtual public abstr_emp{
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):
abstr_emp(fn,ln,j),reportsto(rpo){}
fink(const abstr_emp&e,const string &rpo):
abstr_emp(e),reportsto(rpo){}
fink(const fink& e):
abstr_emp(e),reportsto(e.reportsto){}
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):
abstr_emp(fn,ln,j),manager(fn,ln,j,ico),fink(fn,ln,j,rpo){}
highfink(const abstr_emp& e,const string& rpo,int ico):
abstr_emp(e),manager(e,ico),fink(e,rpo){}
highfink(const fink& f,int ico):
abstr_emp(f),manager((const abstr_emp&)(f),ico),fink(f){}
highfink(const manager& m,const string rpo):
abstr_emp(m),manager(m),fink((const abstr_emp&)(m),rpo){}
highfink(const highfink& h):abstr_emp(h),manager(h),fink(h){}
virtual void ShowAll()const;
virtual void SetAll();
};
注意,该类层次结构使用了带虚基类的MI,所以要牢记这种情况下用于构造函数初始化列表的特殊规则。还需要注意的是,有些方法被声明为保护的。这可以简化二些highfink方法的代码(例如,如果highfink::ShowAll()只是调用fink::ShowAll()和manager::ShwAll(), 则它将调用abstr_emp::ShowAll()两次)。请提供类方法的实现,并在一个程序中对这些类进行测试。下面是一个小型测试程序:
int main(){
employee em("Trip","Harris","Thumper");
cout<<em;
em.ShowAll();
cout<<endl;
manager ma("Amorphia","Spindragon","Nuancer",5);
cout<<ma;
ma.ShowAll();
cout<<endl;
fink fi("Matt","Oggs","Oiler","Juno Barr");
cout<<fi;
fi.ShowAll();
cout<<endl;
highfink hf(ma,"Gurly 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 * tri[4]={&em,&fi,&hf,&hf2};
for(int i=0;i<4;i++)
tri[i]->ShowAll();
return 0;
}
为什么没有定义赋值运算符?
为什么要将ShowAll()和SetAll()定义为虛的?
为什么要将abstr_emp定义为虛基类?
为什么highfink类没有数据部分?
为什么只需要一个operator<<( )版本?
如果使用下面的代码替换程序的结尾部分,将会发生什么情况?
abstr_emp tri[4]={em,fi,hf,hf2};
for(int i=0;i<4;i++)
tri[i].ShowAll();
题解
#include<iostream>
#include<string>
using namespace std;
//**************abstr_emp的声明和实现**************
class abstr_emp{
private:
string fname;
string lname;
string job;
public:
abstr_emp(){};
abstr_emp(const 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 abstr_emp &e);
virtual ~abstr_emp()=0;
};
abstr_emp::~abstr_emp(){}
void abstr_emp::ShowAll()const{
cout<<"Name: "<<fname<<", "<<lname<<endl;
cout<<"Job: "<<job<<endl;
}
void abstr_emp::SetAll(){
cout<<"Enter the firstname: ";
cin>>fname; cin.get();
cout<<"Enter the lastname: ";
cin>>lname; cin.get();
cout<<"Enter the job: ";
getline(cin,job);
}
ostream& operator<<(ostream& os,const abstr_emp &e){
os<<"Name: "<<e.fname<<", "<<e.lname<<endl;
os<<"Job: "<<e.job<<endl;
return os;
}
//**************employee的声明和实现**************
class employee:public abstr_emp{
public:
employee();
employee(const string &fn,const string &ln,const string &j):abstr_emp(fn,ln,j){}
virtual void ShowAll()const;
virtual void SetAll();
};
void employee::ShowAll()const{
abstr_emp::ShowAll();
}
void employee::SetAll(){
abstr_emp::SetAll();
}
//**************manager的声明和实现**************
class manager:virtual public abstr_emp{
private:
int inchargeof;
protected:
int InChargeof()const{return inchargeof;}
int &InChargeof(){return inchargeof;}
public:
manager(){};
manager(const string &fn,const string &ln,const string &j,int ico=0):
abstr_emp(fn,ln,j),inchargeof(ico){}
manager(const abstr_emp& e,int ico):
abstr_emp(e),inchargeof(ico){}
manager(const manager& m):
abstr_emp(m),inchargeof(m.inchargeof){}
virtual void ShowAll()const;
virtual void SetAll();
};
void manager::ShowAll()const{
abstr_emp::ShowAll();
cout<<"Inchargeof: "<<inchargeof<<endl;
}
void manager::SetAll(){
abstr_emp::SetAll();
cout<<"Enter the number of abstr_emps managed: ";
cin>>inchargeof;
cin.get();
}
//**************Fink的声明和实现**************
class fink: virtual public abstr_emp{
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):
abstr_emp(fn,ln,j),reportsto(rpo){}
fink(const abstr_emp&e,const string &rpo):
abstr_emp(e),reportsto(rpo){}
fink(const fink& e):
abstr_emp(e),reportsto(e.reportsto){}
virtual void ShowAll()const;
virtual void SetAll();
};
void fink::ShowAll()const{
abstr_emp::ShowAll();
cout<<"Reportsto: "<<reportsto<<endl;
}
void fink::SetAll(){
abstr_emp::SetAll();
cout<<"Enter the name of whom the fink should report to: ";
getline(cin,reportsto);
}
//**************highfink的声明和实现**************
class highfink:public manager,public fink{
public:
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(const abstr_emp& e,const string& rpo,int ico):
abstr_emp(e),manager(e,ico),fink(e,rpo){}
highfink(const fink& f,int ico):
abstr_emp(f),manager((const abstr_emp&)(f),ico),fink(f){}
highfink(const manager& m,const string rpo):
abstr_emp(m),manager(m),fink((const abstr_emp&)(m),rpo){}
highfink(const highfink& h):abstr_emp(h),manager(h),fink(h){}
virtual void ShowAll()const;
virtual void SetAll();
};
void highfink::ShowAll()const{
abstr_emp::ShowAll();
cout<<"Inchargeof: "<<manager::InChargeof()<<endl;
cout<<"Reportsto: "<<fink::ReportsTo()<<endl;
}
void highfink::SetAll(){
abstr_emp::SetAll();
cout<<"Enter the number of abstr_emps managed: ";
cin>>manager::InChargeof();
cin.get();
cout<<"Enter the name of whom the fink should report to: ";
getline(cin,fink::ReportsTo());
}
int main(){
employee em("Trip","Harris","Thumper");
cout<<em;
em.ShowAll();
cout<<endl;
manager ma("Amorphia","Spindragon","Nuancer",5);
cout<<ma;
ma.ShowAll();
cout<<endl;
fink fi("Matt","Oggs","Oiler","Juno Barr");
cout<<fi;
fi.ShowAll();
cout<<endl;
highfink hf(ma,"Gurly 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 * tri[4]={&em,&fi,&hf,&hf2};
for(int i=0;i<4;i++)
tri[i]->ShowAll();
return 0;
}
//问答题
//1.为什么没有赋值运算符?
//因为没有动态内存分配,所以默认赋值运算符也可以使用,不会导致错误
//2.为什么要把ShowAll和SetAll定义为虚的?
//因为派生类要对这两个数字进行覆写,所以要定义为虚的
//3.为什么要将abstr_emp定义为虚基类?
//因为abstr_emp派生了manager和fink,而manager和fink又多重派生了highfink,此时为了避免包含多个abstr_emp的副本,所以需要定义为虚基类
//4.为什么highfink类没有数据部分?
//因为是多重派生产生的,所以不需要另外添加成员时,只用继承来的父类的成员即可。
//5.为什么只有一个operator<<()版本?
//operator<<()参数为基类的引用,而基类的引用可以指向派生类,所以只有一个
//6.如果用下面的代码替换程序的结尾部分,将会发生什么情况?
// abstr_emp tri[4]={em,fi,hf,hf2};
// for(int i=0;i<4;i++)
// tri[i].ShowAll();
//
// 只会显示名字和职业,因为em,fi,hf,hf2会被强制转为abstr_emp类,所以只会使用基类的方法
Comments | NOTHING