1.Wine 类有一个string 类对象成员(参见第4章)和一个Pair 对象(参见本章)其中前者用于存储葡酒的名称而后者有2个valarray<in对象(参见本章)这两个 valaray<in对象分别保了葡酒的酿造年份和该年生产的瓶数。例如Pair 的第1个 valaray<int对象可能为19881992和1996年第2个alaay<int对象可能为24、48和144瓶。Wine 最好有1个nt 成员用于存储年数另外,一些 typedef 可能有助于简化编程工作:
typedef std::valarrayeints ArrayInt ;
typedef Pair<ArrayInt,ArrayInt> PairArray;
这样,PairArray表示的是类型 Pair<std:valarray<in>std:valaay<in> >使用包含来实现 Wine类并用个简单的程序对其进行测试。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[l);
// initialize label to l, number of years to y.
// create array objects of length y
Winelconst char *l,int y);Wine 类应该有一个GetBottles()方法,它根据 Wine 对象能够存储儿种年份(y),提示用户输入年份和瓶数。方法Label()返回一个指向葡萄酒名称的引用。sm()方法返回 Pair 对象中第二个valaay<in对象中的瓶数总和测试程序应提示用户输入葡萄酒名称、元素个数以及每个元素存储的年份和瓶数等信息。程序将使用这些数据来构造一个 Wine对象,然后显示对象中保存的信息。
下面是一个简单的测试程序:
//pe14-1.cpp-- using Wine class with containment#include ciostream>#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 elementsholding.GetBottles();// solicit input for year, bottle countholding.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 bWine more("Gushing Grape Red",YRS,y.b);
more .Show():cout << "Total bottles for" <e more,Label() // use Label() method<< "; n cc more,sum() c< endl:// use sum() methodcout <<"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
1988
1994
1998
2001
Bottles
42
58
122
144
Wine: Gushing
Grape Red
Year
1993
1995
1998
Bottles
48
60
72
Total bottles for Gushing Grape Red: 180Bye
#include <iostream>
#include "winec.h"
int main()
{
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);
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();
cout << ": " << more.sum() << endl;
cout << "Bye\n";
return 0;
}
#ifndef WINEC_H_
#define WINEC_H_
#include <string>
#include <valarray>
#include <iostream>
using namespace std;
template <typename T1, typename T2>
class Pair
{
private:
T1 year;
T2 bottles;
public:
Pair() {}
Pair(const T1 &yr, const T2 &bt) : year(yr), bottles(bt) {}
void Set(const T1 &yr, const T2 &bt);
int Sum() const;
void Show(int y) const;
};
template <typename T1, typename T2>
void Pair<T1, T2>::Set(const T1 &yr, const T2 &bt)
{
year = yr;
bottles = bt;
}
template <typename T1, typename T2>
int Pair<T1, T2>::Sum() const
{
return bottles.sum();
}
template <typename T1, typename T2>
void Pair<T1, T2>::Show(int y) const
{
for (int i = 0; i < y; i++)
{
cout << "\t" << year[i] << "\t" << bottles[i] << endl;
}
}
typedef valarray<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;
class Wine
{
private:
string wine_name;
PairArray year_and_bottle;
int year;
public:
Wine(const char *l, int y);
Wine(const char *l, int y, const int yr[], const int bot[]);
~Wine();
void GetBottles();
string &Label();
int sum() const;
void Show() const;
};
#endif
#include "winec.h"
Wine::Wine(const char *l, int y)
{
wine_name = l;
year_and_bottle.Set(ArrayInt(y), ArrayInt(y));
year = y;
}
Wine::Wine(const char *l, int y, const int yr[], const int bot[])
{
wine_name = l;
year_and_bottle.Set(ArrayInt(yr, y), ArrayInt(bot, y));
year = y;
}
Wine::~Wine()
{
}
void Wine::GetBottles()
{
ArrayInt yr(year);
ArrayInt bt(year);
cout << "Enter " << wine_name;
cout << " data for " << year << " year(s):" << endl;
for (int i = 0; i < year; i++)
{
cout << "Enter year: ";
cin >> yr[i];
cout << "Enter bottles for that year: ";
cin >> bt[i];
}
year_and_bottle.Set(yr, bt);
}
string &Wine::Label()
{
return wine_name;
}
int Wine::sum() const
{
return year_and_bottle.Sum();
}
void Wine::Show() const
{
cout << "Wine: " << wine_name << endl;
cout << "\tYear\tBottles" << endl;
year_and_bottle.Show(year);
}
2.采用私有继承而不是包含来完成编程练习 1。同样,一些 yedef 可能会有所帮助,另外,您可能还需要考电诸如下面这样的语句的含义:
PairArray::operator=(PairArray(ArrayInt [),ArrayInt()));cout cc(const string &)(*this);
您设计的类应该可以使用编程练习1中的测试程序进行测试。
#include <iostream>
#include "winec.h"
int main()
{
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);
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();
cout << ": " << more.sum() << endl;
cout << "Bye\n";
return 0;
}
#ifndef WINEC_H_
#define WINEC_H_
#include <string>
#include <valarray>
#include <iostream>
using namespace std;
template <typename T1, typename T2>
class Pair
{
private:
T1 year;
T2 bottles;
public:
Pair() {}
Pair(const T1 &yr, const T2 &bt) : year(yr), bottles(bt) {}
int Sum() const;
void Show(int y) const;
};
template <typename T1, typename T2>
int Pair<T1, T2>::Sum() const
{
return bottles.sum();
}
template <typename T1, typename T2>
void Pair<T1, T2>::Show(int y) const
{
for (int i = 0; i < y; i++)
{
cout << '\t' << year[i] << '\t' << bottles[i] << endl;
}
}
typedef valarray<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;
class Wine : private string, private PairArray
{
private:
int year;
public:
Wine(const char *l, int y);
Wine(const char *l, int y, const int yr[], const int bot[]);
~Wine();
void GetBottles();
string &Label();
int sum() const;
void Show() const;
};
#endif
#include "winec.h"
Wine::Wine(const char *l, int y) : string(l)
{
PairArray::operator=(PairArray(ArrayInt(y), ArrayInt(y))); //使用隐式赋值运算符调用私有对象构造函数进行初始化;
year = y;
}
Wine::Wine(const char *l, int y, const int yr[], const int bot[]) : string(l)
{
PairArray::operator=(PairArray(ArrayInt(yr, y), ArrayInt(bot, y))); //使用隐式赋值运算符调用私有对象构造函数进行初始化;
year = y;
}
Wine::~Wine()
{
}
void Wine::GetBottles()
{
ArrayInt yr(year);
ArrayInt bt(year);
cout << "Enter " << (const string &)*this;
cout << " data for " << year << " year(s):" << endl;
for (int i = 0; i < year; i++)
{
cout << "Enter year: ";
cin >> yr[i];
cout << "Enter bottles for that year: ";
cin >> bt[i];
}
PairArray::operator=(PairArray(yr, bt));
}
string &Wine::Label()
{
return (string &)*this; //使用强制类型转换访问私有对象;
}
int Wine::sum() const
{
return PairArray::Sum();
}
void Wine::Show() const
{
cout << "Wine: " << (const string &)(*this) << endl;
cout << "\tYear\tBottles" << endl;
PairArray::Show(year);
}
3.定义一个QucueTp 模板。然后在一个类似于程序清单14.12 的程序中创建一个指向 Worker 的指针队列(参见程序清单14.10中的定义),并使用该队列来测试它。
#include <iostream>
#include <cstring>
#include "worker.h"
#include "queuetp.h"
const int SIZE = 5;
int main()
{
using std::cin;
using std::cout;
using std::endl;
using std::strchr;
int ct;
Worker *temp;
QueueTp<Worker *> lolas(SIZE);
for (ct = 0; ct < SIZE; ct++)
{
char choice;
cout << "Enter the menu order:" << endl;
cout << "a: add a worker to queue." << endl;
cout << "d: delete a worker from queue." << endl;
cout << "q: quit." << endl;
cin >> choice;
while (NULL == strchr("adq", choice))
{
cout << "Please enter a, d or q: ";
cin >> choice;
}
if ('q' == choice)
{
break;
}
switch (choice)
{
case 'a':
{
temp = new Worker;
cin.get();
if (lolas.isfull()) //若是队列已满则打印信息并释放new分配的内存;
{
cout << "Queue is full!" << endl;
delete temp;
}
else
{
temp->Set();
lolas.enqueue(temp);
}
break;
}
case 'd':
{
if (lolas.isempty())
{
cout << "Queue is empty!" << endl;
}
else
{
lolas.dequeue(temp);
}
break;
}
}
}
ct = lolas.queuecount();
cout << "\nHere is " << ct << " worker(s) in queue:" << endl;
for (int i = 0; i < ct; i++)
{
lolas.dequeue(temp);
temp->Show();
}
cout << "Done.\n";
return 0;
}
#ifndef QUEUETP_H_
#define QUEUETP_H_
template <typename Item>
class QueueTp
{
private:
enum{ Q_SIZE = 10 };
struct Node
{
Item item;
struct Node *next;
};
Node *front;
Node *rear;
int items;
const int qsize;
QueueTp(const QueueTp &q) : qsize(0) {}
QueueTp &operator=(const QueueTp &q) { return *this; }
public:
QueueTp(int qs = Q_SIZE);
~QueueTp();
bool isempty() const;
bool isfull() const;
int queuecount() const;
bool enqueue(const Item &item);
bool dequeue(Item &item);
};
template <typename Item>
QueueTp<Item>::QueueTp(int qs) : qsize(qs)
{
front = rear = nullptr;
items = 0;
}
template <typename Item>
QueueTp<Item>::~QueueTp()
{
Node *temp;
while (front != nullptr)
{
temp = front;
front = front->next;
delete temp;
}
}
template <typename Item>
bool QueueTp<Item>::isempty() const
{
return 0 == items;
}
template <typename Item>
bool QueueTp<Item>::isfull() const
{
return qsize == items;
}
template <typename Item>
int QueueTp<Item>::queuecount() const
{
return items;
}
template <typename Item>
bool QueueTp<Item>::enqueue(const Item &item)
{
if (isfull())
{
return false;
}
Node *add = new Node;
add->item = item;
add->next = nullptr;
++items;
if (nullptr == front)
{
front = add;
}
else
{
rear->next = add;
}
rear = add;
return true;
}
template <typename Item>
bool QueueTp<Item>::dequeue(Item &item)
{
if (isempty())
{
return false;
}
item = front->item;
--items;
Node *temp = front;
front = front->next;
delete temp;
if (0 == items)
{
rear = nullptr;
}
return true;
}
#endif
#ifndef WORKER_H_
#define WORKER_H_
#include <string>
class Worker
{
private:
std::string fullname;
long id;
public:
Worker() : fullname("no one"), id(0L) {}
Worker(const std::string &s, long n) : fullname(s), id(n) {}
~Worker();
void Set();
void Show() const;
};
#endif
4.Pcrson 类保存人的名和姓。除构造函数外,它还有 Show( )方法,用于显示名和姓。Guslinger 类以Person类为虚基类派生而来,它包含一个Draw( )成员,该方法返回一个double值,表示枪手的拔枪时间。这个类还包含一个int 成员,表示枪手枪上的刻痕数。最后,这个类还包含一个 Show()两数,用于显示所有这些信息。
PokerPlayer 类以Person类为虚基类派生而来。它包含一个Draw( )成员该函数返回一个1~52的随机数,用于表示扑克牌的值(也可以定义一个 Card 类,其中包含花色和面值成员,然后让 Draw( )返回一个Card对象)。PokerPlayer类使用 Person 类的 show()数。BadDude( )类从Gunslingcr和 PokerPlayer类公有派生而来。它包含 Gdraw()成员(返回坏蛋拔枪的时间)和Cdraw()成员(返回下一张扑克牌),另外还有一个合适的 Show()函数。请定义这些类和方法以及其他必要的方法(如用于设置对象值的方法),并使用一个类似于程序清单14.12 的简单程序对它们进行测试。
#include <iostream>
#include <cstring>
#include "personmi.h"
const int SIZE = 5;
int main()
{
using std::cin;
using std::cout;
using std::endl;
using std::strchr;
int i, ct;
Person *people[SIZE];
for (ct = 0; ct < SIZE; ct++)
{
char choice;
cout << "Enter the person category:" << endl;
cout << "g: gunslinger" << endl;
cout << "p: pokerplayer" << endl;
cout << "b: baddude" << endl;
cout << "q: quit" << endl;
cin >> choice;
while (NULL == strchr("bgpq", choice))
{
cout << "Please enter b, g, p or q: ";
cin >> choice;
}
if ('q' == choice)
{
break;
}
switch (choice)
{
case 'b':
{
people[ct] = new BadDude;
break;
}
case 'g':
{
people[ct] = new Gunslinger;
break;
}
case 'p':
{
people[ct] = new PokerPlayer;
break;
}
}
cin.get();
people[ct]->Set();
}
cout << "\nHere is your message for some people:" << endl;
for (i = 0; i < ct; i++)
{
cout << endl;
people[i]->Show();
}
for (i = 0; i < ct; i++)
{
delete people[i];
}
cout << "Bye.\n";
return 0;
}
#ifndef PERSONMI_H_
#define PERSONMI_H_
#include <string>
using std::string;
class Person
{
private:
string firstname;
string lastname;
protected:
virtual void Data() const; //虚保护方法打印基类成员信息, 使得派生类可以间接访问;
virtual void Get(); //虚保护方法获取基类成员信息, 使得派生类可以间接访问;
public:
Person() : firstname("no"), lastname("one") {}
Person(const string &fname, const string &lname) : firstname(fname), lastname(lname) {}
virtual ~Person() = 0;
virtual void Set() = 0;
virtual void Show() const = 0;
};
class Gunslinger : virtual public Person
{
private:
int nicks;
protected:
void Data() const; //重新定义保护方法;
void Get();
public:
Gunslinger() : Person(), nicks(0) {}
Gunslinger(const string &f, const string &l, int n) : Person(f, l), nicks(n) {}
Gunslinger(const Person &p, int n) : Person(p), nicks(n) {}
void Set();
void Show() const;
double Draw() const; //打印枪手的拔枪时间;
};
class PokerPlayer : virtual public Person
{
protected:
void Data() const; //重新定义保护方法;
public:
PokerPlayer() : Person("no", "one") {}
PokerPlayer(const string &f, const string &l) : Person(f, l) {}
PokerPlayer(const Person &p) : Person(p) {}
void Set();
void Show() const;
int Draw() const; //表示扑克牌的值;
};
class BadDude : public Gunslinger, public PokerPlayer
{
protected:
void Data() const; //重新定义保护方法;
void Get();
public:
BadDude() {}
BadDude(const string &f, const string &l, int n) : Person(f, l), Gunslinger(f, l, n), PokerPlayer(f, l) {}
BadDude(const Person &p, int n) : Person(p), Gunslinger(p, n), PokerPlayer(p) {}
BadDude(const Gunslinger &g) : Person(g), Gunslinger(g), PokerPlayer(g) {}
BadDude(const PokerPlayer &p, int n) : Person(p), Gunslinger(p, n), PokerPlayer(p) {}
void Set();
void Show() const;
double Gdraw() const; //打印坏蛋拔枪的时间;
int Cdraw() const; //打印下一张扑克牌的值;
};
#endif
#include <iostream>
#include <cstdlib>
#include "personmi.h"
using namespace std;
Person::~Person()
{
}
void Person::Data() const
{
cout << "First name: " << firstname << endl;
cout << "Last name: " << lastname << endl;
}
void Person::Get()
{
cout << "Please enter your first name: ";
getline(cin, firstname);
cout << "Please enter your last name: ";
getline(cin, lastname);
}
void Gunslinger::Data() const
{
cout << "Gunslinger nicks: " << nicks << endl;
}
void Gunslinger::Get()
{
cout << "Please enter the nicks for gunslinger: ";
cin >> nicks;
while (cin.get() != '\n')
continue;
}
void Gunslinger::Set()
{
cout << "Enter Gunslinger name" << endl;
Person::Get();
Get();
}
void Gunslinger::Show() const
{
cout << "Category: Gunslinger" << endl;
Person::Data();
Data();
}
double Gunslinger::Draw() const
{
return double(rand() % 5 + 1); //枪手的拔枪时间设置为1到5之间的值;
}
void PokerPlayer::Data() const
{
cout << "The cards: " << Draw() << endl;
}
void PokerPlayer::Set()
{
cout << "Enter PokerPlayer name" << endl;
Person::Get();
}
void PokerPlayer::Show() const
{
cout << "Category: PokerPlayer" << endl;
Person::Data();
Data();
}
int PokerPlayer::Draw() const //扑克牌的值;
{
return rand() % 52 + 1;
}
void BadDude::Data() const
{
Gunslinger::Data();
PokerPlayer::Data();
cout << "The time for a bad guy to draw his gun is " << Gdraw() << endl;
cout << "The next card is " << Cdraw() << endl;
}
void BadDude::Get()
{
Gunslinger::Get();
}
void BadDude::Set()
{
cout << "Enter BadDude name" << endl;
Person::Get();
Get();
}
void BadDude::Show() const
{
cout << "Category: BadDude" << endl;
Person::Data();
Data();
}
double BadDude::Gdraw() const
{
return Gunslinger::Draw();
}
int BadDude::Cdraw() const
{
return PokerPlayer::Draw();
}
5.下面是一些雷声明:
// emp.h -- header file for abstr_emp class and children
#include ciostream>#include catringx
class abstr emp
private :
// abstremp's first namestd ::string fname ;
std::string lname;// abstr_emp's last name
std;:atring job;
public:
abstr_empl);
abatr_empiconst std::string k fn, const std::string 6 ln,const std::string & j);virtual void ShowAll] const;// labels and shows all datavirtual void SetAl1(),/ prompts user for valuesfriend std;iostream k
operatorcc(std;:ostream k o8, const abstr emp & e);// just displays first and last name// virtual base classvirtual -abstrempl)m0;
class employee : public abstr emp
public:
employee(l;
employee(const std;istring 5 fn,const std;:string 点 ln,const std;string & j;virtual void ShowAll() const;virtual void SetAl1();
tr
class manager: virtual public abstr emp
private:int inchargeof;// number of abatr emps managedprotected:
int InCharge0f () const return inchargeof; // outputint & InChargeOfl! return inehargeof ;// inputpublie:
manager():manager(const std::string & fn, const std::string 5 In.const atd::string j, int ico 0;manager(const abetr_emp & e,int ico] ?
manager(const manager & m) :
virtual void ShowAll() const :
virtual vold SetAl1 ();
clagm fink; virtual public abatr emp
private:
std::string reportsto;protected;..2ri
..:to whomfink reports
.const atd=;string ReportsTol) const -[ return-reportsto;std::string & ReportsTo() return reportsto;public:·.-
fink(》;
fink(const std::string &fn, const std::string 6 In,conststd!:string j,const std::string arpolifinkIconstabstr-emp se,const std::string .rpol:fink(consttink & e)virtuaFvoid-ShowAll[-const;virtual void SetAlIU
class highfink:public manager,public fink // managementfink-
public-
highfink(Congtstd:::string' fn,const std::string&.In,;const_std?:string &const'std;rstring 5rpo.intvicor+-TI
highfink(const abstr_emp& e,.const;std::string & rpo;int ico);
highfink(const,fink &f,int.ico).
highfinklconst manager &m,const std::string& rpol;
highfinklconst highfink & h .
virtual void ShowAl1[),const;virtua] voidSetAll(F;:-
注意,该类层次结构使用子带虚基类的 MI,所以要牢记这种情况下用于构造函数初始化列表的特殊规则。还需要注意的是,有些方法被声明为保护的。这可以简化一些 hihfink-方法的代码例如,如果highfinkShowAll)只是调用finkShowAH()和 manager:ShwAl( )则它将调用abstemp::ShowAll()两次)。请提供类方法的实现,并在一个程序中对这些类进行测试。下面是一个小型测试程序:
/pe14-5:cPP//useemp1-cPP
--_usingthe'abstr emp,classes
--
#include <iostream>using,namespace std;#inElude "emp,h"ac
int main(voidl
employeeem("Trip","Harr""Thumper")-cout << em <s endl;em,ShowA11(l;managerma["Amorphia","Spindragon'"Nuancer!.-5);cout << ma <<endl;
ma,showAIIT]:
fink'fi("Matt","Oggs","Oiler”,"Juno Barr");cout cc fi *<endl;fi.ShowAl1();highfink hf (ma,"Curly Kew"); // recruitment?hf.showAl1();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] {5em,&fi,&hf,&hf2);for (int im0;i< 4;1++)tri[1]->ShowAl1(];
return 0;
为什么没有定义赋值运算符?为什么要将 showA11()和 SetA11()定义为的?为什么要将abstr_emp 定义为虚基类?为什么highfink 类没有数据部分?为什么只需要一个 operator<<()版本?如果使用下面的代码替换程序的结尾部分,将会发生什么情况?
abstr_emp tri[] - (em,fi,hf,hf2);
for (inti=0;ic4;i++)
tri[i].ShowAll();
#include <iostream>
using namespace std;
#include "emp.h"
int main()
{
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";
abstr_emp *tri[4] = {&em, &fi, &hf, &hf2};
for (int i = 0; i < 4; i++)
{
tri[i]->ShowAll();
}
return 0;
}
#ifndef EMP_H_
#define EMP_H_
#include <iostream>
#include <string>
class abstr_emp
{
private:
std::string fname;
std::string lname;
std::string job;
public:
abstr_emp();
abstr_emp(const std::string &fn, const std::string &ln, const std::string &j);
virtual void ShowAll() const;
virtual void SetAll();
friend std::ostream &operator<<(std::ostream &os, const abstr_emp &e);
virtual ~abstr_emp() = 0;
};
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;
protected:
int InChargeOf() const { return inchargeof; } //令派生类能够访问基类成员;
int &InChargeOf() { return inchargeof; } //令派生类能够访问基类成员并进行修改;
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 ShowAll() const;
virtual void SetAll();
};
class fink : virtual public abstr_emp
{
private:
std::string reportsto;
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 &e);
virtual void ShowAll() const;
virtual void SetAll();
};
class highfink : public manager, public 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
#include <iostream>
#include <string>
#include "emp.h"
using std::cin;
using std::cout;
using std::endl;
using std::string;
abstr_emp::abstr_emp() : fname("no"), lname("one"), job("none")
{
}
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 << "First name: " << fname << endl;
cout << "Last name: " << lname << endl;
cout << "Job: " << job << endl;
}
void abstr_emp::SetAll()
{
cout << "Please enter your firstname: ";
getline(cin, fname);
cout << "Please enter your lastname: ";
getline(cin, lname);
cout << "Please enter your job: ";
getline(cin, job);
}
std::ostream &operator<<(std::ostream &os, const abstr_emp &e)
{
os << "First name: " << e.fname << endl;
os << "Last name: " << e.lname << endl;
os << "Job: " << e.job;
return os;
}
abstr_emp::~abstr_emp()
{
}
employee::employee() : abstr_emp()
{
}
employee::employee(const string &fn, const string &ln, const string &j) : abstr_emp(fn, ln, j)
{
}
void employee::ShowAll() const
{
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
{
abstr_emp::ShowAll();
cout << "In charge of: " << inchargeof << endl;
}
void manager::SetAll()
{
abstr_emp::SetAll();
cout << "Please enter a number for inchargerof: ";
cin >> inchargeof;
while (cin.get() != '\n')
continue;
}
fink::fink() : abstr_emp(), reportsto("none")
{
}
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
{
abstr_emp::ShowAll();
cout << "Reports to: " << reportsto << endl;
}
void fink::SetAll()
{
abstr_emp::SetAll();
cout << "Please enter a string for 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 &f, int ico) : abstr_emp(f), manager(f, ico), fink(f)
{
}
highfink::highfink(const manager &m, const 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();
cout << "In charge of: " << manager::InChargeOf() << endl;
cout << "Reports to: " << fink::ReportsTo() << endl;
}
void highfink::SetAll()
{
abstr_emp::SetAll();
cout << "Please enter a number for inchargerof: ";
cin >> InChargeOf();
while (cin.get() != '\n')
continue;
cout << "Please enter a string for reportsto: ";
getline(cin, ReportsTo());
}
(1):因为没有使用new进行动态内存分配因此使用的是隐式赋值运算符。
(2):在派生类中进行了再次定义,所以声明为虚函数。
(3):使得从多个类(基类相同)派生出的对象只继承1个基类对象。
(4):没有新增的数据成员,继承过来的数据成员需用基类方法间接访问。
(5):因为只访问对象中的3个数据部分,其余部分未进行访问。
(6):编译器将会报错,抽象基类不能进行实例化,但可以使用抽象基类的指针来访问派生出来的多个不同类。