第十四章:C++中的代码继承
一、复习题
1. a. 公有派生;b. 私有派生;c. 公有派生;d. 公有派生;e. 公有派生
2.
Gloam::Gloam(int g, const char * s)
{
Frabjous(s);
glip = g;
}
Gloam::Gloam(int g, const Frabjous & f)
{
glip = g;
Frabjous(f);
}
void Gloam::tell()
{
fb.show();
cout << glip;
}
3.
Gloam::Gloam(int g, const char* s) : Frabjous(s)
{
glip = g;
}
Gloam::Gloam(int g, const Frabjous & f) : Frabjous(f)
{
glip = g;
}
void Gloam::tell()
{
Frabjous::tell();
cout << glip;
}
4.
class Stack
{
private:
enum { MAX = 10 };
Worker* items[MAX];
int top;
public:
Stack();
bool isempty();
bool isfull();
bool push(const Worker* & item);
bool pop(Worker * & item);
};
5.
1. Array<string> arrString;
2. Stack<double> stackDB;
3. Array<Stack<Worker *>> arrStack;
4. 4个
6. 虚基类的派生类只会从虚途径中继承一个虚基类对象,而非虚基类的派生类会从多个继承途径继承多个基类对象;此外,虚基类的派生类的接口在定义时语法与非基类的派生类有所不同。
二、编程练习
1.
#ifndef C_PRIMER_14_WINE_H
#define C_PRIMER_14_WINE_H
#include <iostream>
#include <valarray>
using std::pair,std::string,std::cout,std::endl,std::cin;
class Wine
{
private:
typedef std::valarray<int> ArrayInt;
typedef pair<ArrayInt,ArrayInt> PairArray;
string name;
PairArray data;
int number;
public:
Wine(const char * s, int n, int yr[], int bot[]);
Wine(const char * s, int n);
void Getbottles();
string & Label() {return name;}
int sum() const;
void show() const;
};
Wine::Wine(const char *s, int n, int yr[], int bot[])
{
name = s;
number = n;
ArrayInt a1(n);
ArrayInt a2(n);
for(int i = 0; i < n; i++)
{
a1[i] = yr[i];
a2[i] = bot[i];
}
data = std::make_pair(a1,a2);
}
Wine::Wine(const char *s, int n)
{
name = s;
number = n;
ArrayInt a1(n);
ArrayInt a2(n);
data = std::make_pair(a1,a2);
}
void Wine::Getbottles()
{
cout << "Enter " << name << " data for " << number << " year(s) : " << endl;
for(int i = 0; i < number; i++)
{
cout << "Enter year: ";
cin >> data.first[i];
cout << "Enter bottles for that year: ";
cin >> data.second[i];
}
}
int Wine::sum() const {
return data.second.sum();
}
void Wine::show() const
{
cout << "Wine: " << name << endl;
cout << "\t Year\tBottles" << endl;
for(int i = 0;i < number;i++)
{
cout << "\t " << data.first[i] << "\t" << data.second[i] << endl;
}
}
#endif //C_PRIMER_14_WINE_H
#include "Wine.h"
#include <iostream>
int main()
{
using std::cin;
using std::cout;
using std::endl;
cout << "Enter name of the 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;
return 0;
}
2.
#ifndef C_PRIMER_14_WINE_H
#define C_PRIMER_14_WINE_H
#include <iostream>
#include <valarray>
using std::pair,std::string,std::cout,std::endl,std::cin;
typedef std::valarray<int> ArrayInt;
typedef pair<ArrayInt,ArrayInt> PairArray;
class Wine : private string , private PairArray , private ArrayInt
{
private:
int number;
public:
Wine(const char * s, int n, int yr[], int bot[]);
Wine(const char * s, int n);
void Getbottles();
string & Label();
int sum() const;
void show() const;
};
Wine::Wine(const char *s, int n, int yr[], int bot[]) : string(s),number(n),PairArray(ArrayInt (yr,n),ArrayInt (bot,n))
{
}
Wine::Wine(const char *s, int n) : string(s),number(n),PairArray(ArrayInt (0,n),ArrayInt (0,n))
{
}
void Wine::Getbottles()
{
ArrayInt a(number);
ArrayInt b(number);
cout << "Enter " << (const string&)*this << " data for " << number << " year(s) : " << endl;
for(int i = 0; i < number; i++)
{
cout << "Enter year: ";
cin >> a[i];
cout << "Enter bottles for that year: ";
cin >> b[i];
}
(PairArray &)*this = std::make_pair(a,b);
}
int Wine::sum() const {
int sum_all = 0;
for(int i = 0;i<number;i++)
sum_all += PairArray ::second[i];
return sum_all;
}
void Wine::show() const
{
cout << "Wine: " << (string&)*this << endl;
cout << "\t Year\tBottles" << endl;
for(int i = 0;i < number;i++)
{
cout << "\t " << PairArray ::first[i] << "\t" << PairArray ::second[i] << endl;
}
}
string &Wine::Label() {
return (string&)*this;
}
#endif //C_PRIMER_14_WINE_H
#include "Wine.h"
#include <iostream>
int main()
{
using std::cin;
using std::cout;
using std::endl;
cout << "Enter name of the 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;
return 0;
}
3.
#ifndef C_PRIMER_14_QUEUETP_H
#define C_PRIMER_14_QUEUETP_H
#include <iostream>
template<class T>
class QueueTp {
private:
enum {
SIZE = 3
};
int size;
T *arr;
int top;
public:
QueueTp() : size(SIZE), top(0) { arr = new T[SIZE]; }
explicit QueueTp(int s) : size(s), top(0) { arr = new T[size]; }
~QueueTp() { delete[] arr; }
bool isFull() { return top == size; }
bool isEmpty() { return top == 0; }
bool push(T item);
bool pop(T &item);
};
template<class T>
bool QueueTp<T>::push(T item) {
if (isFull()) return false;
arr[top++] = item;
return true;
}
template<class T>
bool QueueTp<T>::pop(T &item) {
if (isEmpty()) return false;
item = arr[--top];
return true;
}
class Worker {
private:
std::string name;
long id;
protected:
virtual void data() const;
virtual void get();
public:
Worker() : name("none"), id(0L) {}
Worker(const std::string &s, long n) : name(s), id(n) {}
virtual ~Worker() = 0;
virtual void set() = 0;
virtual void show() const = 0;
};
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) {}
explicit Waiter(const Worker &wk, int p = 0) : Worker(wk), panache(p) {}
void set();
void show() const;
};
class Singer : virtual public Worker {
protected:
void data() const;
void get();
enum {
other, alto, contralto, sprano, baritone, teror
};
enum {
VType = 7
};
private:
static char *pv[VType];
int voice;
public:
Singer() : Worker(), voice(0) {}
Singer(const std::string &s, long n, int v = 0) : Worker(s, n), voice(v) {}
explicit Singer(const Worker &wk, int v = 0) : Worker(wk), voice(v) {}
void set();
void show() const;
};
class SingerWaiter : public Singer, public Waiter {
protected:
void data() const;
void get();
public:
SingerWaiter() {}
SingerWaiter(const std::string &s, long n, int v = 0, int p = 0)
: Worker(s, n), Singer(s, n, v), Waiter(s, n, p) {}
explicit SingerWaiter(const Worker &wk, int p = 0, int v = 0)
: Worker(wk), Singer(wk, v), Waiter(wk, p) {}
explicit SingerWaiter(const Waiter &wt, int v = 0)
: Waiter(wt), Singer(wt, v) {}
explicit SingerWaiter(const Singer &sg, int p = 0)
: Singer(sg), Waiter(sg, p) {}
void set();
void show() const;
};
#endif //C_PRIMER_14_QUEUETP_H
#include "QueueTp.h"
#include <iostream>
using std::cout, std::endl, std::cin;
Worker::~Worker() {}
void Worker::data() const {
cout << "name: " << name << endl;
cout << "id: " << id << endl;
}
void Worker::get() {
getline(cin, name);
cout << "Please enter id:\n";
cin >> id;
}
void Waiter::get() {
cout << "Enter panache:\n";
cin >> panache;
while (cin.get() != '\n');
}
void Waiter::data() const {
cout << "panache: " << panache << endl;
}
void Waiter::set() {
cout << "Please enter name:\n";
Worker::get();
get();
}
void Waiter::show() const {
cout << "Category: waiter:\n";
Worker::data();
data();
}
char *Singer::pv[Singer::VType] = {"other", "alto",
"sprano", "contralta",
"bass", "baritone", "teror"};
void Singer::data() const {
cout << "voice: " << voice << endl;
}
void Singer::get() {
cout << "Enter the number of the singer's range\n";
for (int i = 0; i < VType; ++i) {
cout << i << ": " << pv[i] << endl;
}
cin >> voice;
while (cin.get() != '\n');
}
void Singer::set() {
cout << "Please enter name:\n";
Worker::get();
get();
}
void Singer::show() const {
cout << "Category singer:\n";
Worker::data();
data();
}
void SingerWaiter::data() const {
Singer::data();
Waiter::data();
}
void SingerWaiter::get() {
Singer::get();
Waiter::get();
}
void SingerWaiter::set() {
cout << "Please enter name:\n";
Worker::get();
get();
}
void SingerWaiter::show() const {
cout << "Category singerwaiter:\n";
Worker::data();
data();
}
#include<iostream>
#include<cstring>
#include"QueueTp.h"
using std::cin;
using std::cout;
using std::endl;
using std::string;
const int len = 10;
QueueTp<Worker *> que(len);
int main() {
char ch;
for (int i = 0; i < len; i++) {
cout << "w:waiter s:singer t:singerwaiter\n"
<< "q to quit." << endl;
cin >> ch;
while (std::strchr("wstq", ch) == NULL)
cout << "please enter w s t q!\n";
if (ch == 'q') break;
switch (ch) {
case 'w':
que.push(new Waiter);
break;
case 's':
que.push(new Singer);
break;
case 't':
que.push(new SingerWaiter);
break;
}
while (cin.get() != '\n')
cin.get();
}
Worker *temp = nullptr;
while (que.pop(temp)) {
temp->show();
cout << endl;
delete temp;
}
return 0;
}
4.
#ifndef C_PRIMER_14_PERSON_H
#define C_PRIMER_14_PERSON_H
#include <iostream>
using std::string,std::cout,std::endl;
class Person
{
private:
string lastName;
string firstName;
protected:
void data() const
{
cout << "lastName: " << lastName << endl;
cout << "firstName: " << firstName << endl;
}
public:
Person():lastName("none"),firstName("none"){}
Person(const string&l,const string & f):lastName(l),firstName(f){}
virtual ~Person(){}
virtual void show(){data();}
};
class Gunslinger : virtual public Person
{
private:
double time;
int notch;
protected:
void data() const
{
cout << "time: " << time << endl;
cout << "notch: " << notch << endl;
}
public:
Gunslinger():Person(),notch(0){}
Gunslinger(const string&l,const string & f,int n,int t):Person(l,f),notch(n),time(t){}
Gunslinger(const Person& p,int n,int t): Person(p),notch(n),time(t){}
double Draw(){return time;}
void show() {Person::data();data();}
};
class PokerPlayer : virtual public Person
{
public:
PokerPlayer():Person(){}
PokerPlayer(const string&l,const string & f):Person(l,f){}
PokerPlayer(const Person& p):Person(p){}
int Draw(){return std::rand()%53 + 1;}
void show(){Person::show();}
};
class BadDude : public PokerPlayer,public Gunslinger
{
protected:
void data() const
{
Gunslinger::data();
}
public:
BadDude():PokerPlayer(),Gunslinger(){}
BadDude(const string&l,const string & f,int n,int nb):Person(l,f),Gunslinger(l,f,n,nb),PokerPlayer(l,f){}
BadDude(const Person& p,int n,int nb):Person(p),Gunslinger(p,n,nb),PokerPlayer(p){}
int Gdraw() {return PokerPlayer::Draw();}
int Cdraw() {return std::rand()%53+1;}
void show() {
Person::data();
data();
}
};
#endif //C_PRIMER_14_PERSON_H
#include"Person.h"
int main()
{
Person p("Tree","Bird");
Gunslinger g("Tree","Bird", 3,1);
PokerPlayer po("shana","Bird");
BadDude b("yuuji","Bird", 2, 1);
Person *ptr = &p;
ptr->show();
ptr = &g;
ptr->show();
ptr = &po;
ptr->show();
ptr = &b;
ptr->show();
return 0;
}
5.
#ifndef C_PRIMER_14_ABSTR_EMP_H
#define C_PRIMER_14_ABSTR_EMP_H
#include <iostream>
#include <string>
class abstr_emp
{
private:
std::string fName;
std::string lName;
std::string job;
public:
abstr_emp():fName("none"),lName("none"),job("none"){}
abstr_emp(const std::string& fn,const std::string& ln
,const std::string& j):fName(fn),lName(ln),job(j){}
virtual ~abstr_emp(){}
virtual void showAll() const;
virtual void SetAll();
friend std::ostream & operator<<(std::ostream& os, abstr_emp& e);
};
class employee : public abstr_emp
{
public:
employee() : abstr_emp(){}
employee(const std::string& fn,const std::string& ln
,const std::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 in_chargeOf() const {return inChargeOf;}
int & in_chargeOf() {return inChargeOf;}
public:
manager():abstr_emp(){}
manager(const std::string& fn,const std::string& ln
,const std::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);
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():abstr_emp(){}
fink(const std::string& fn,const std::string& ln
,const std::string& j,const std::string& r):abstr_emp(fn,ln,j),reportSto(r){}
fink(const abstr_emp& e,const std::string& r) : abstr_emp(e),reportSto(r){}
fink(const fink& f);
virtual void showAll() const;
virtual void SetAll();
};
class highfink : public manager,public fink
{
public:
highfink():abstr_emp(),manager(),fink(){}
highfink(const std::string& fn,const std::string& ln
,const std::string& j,const std::string& r,int ico = 0)
:abstr_emp(fn,ln,j),manager(fn,ln,j,ico),fink(fn,ln,j,r){}
highfink(const abstr_emp& e,const std::string& r,int ico = 0):abstr_emp(e),
manager(e,ico),fink(e,r){}
highfink(const manager& m,const std::string& r):abstr_emp((const abstr_emp&)m),manager(m),fink((const abstr_emp&)m,r){}
highfink(const fink& m,int ico = 0):abstr_emp((const abstr_emp&)m),manager((const abstr_emp&)m,ico),fink(m){}
highfink(const highfink& hf);
virtual void showAll() const;
virtual void SetAll();
};
#endif //C_PRIMER_14_ABSTR_EMP_H
#include "abstr_emp.h"
#include <iostream>
using std::cout,std::endl,std::cin;
void abstr_emp::showAll() const
{
cout << "FirstName: " << fName << endl;
cout << "LastName: " << lName << endl;
cout << "Job: " << job << endl;
}
void abstr_emp::SetAll()
{
cout <<"please enter fname:";
cin >> fName;
cout <<"please enter lname:";
cin >> lName;
cout <<"please enter job:";
cin >> job;
}
std::ostream &operator<<(std::ostream &os, abstr_emp &e) {
os << "FirstName: " << e.fName << endl;
os << "LastName: " << e.lName << endl;
os << "Job: " << e.job << endl;
return os;
}
void employee::showAll() const
{
abstr_emp::showAll();
}
void employee::SetAll()
{
abstr_emp::SetAll();
}
manager::manager(const manager &m) : abstr_emp((const abstr_emp&)m)
{
inChargeOf = m.inChargeOf;
}
void manager::showAll() const {
abstr_emp::showAll();
cout << "inChargeOf: " << inChargeOf << endl;
}
void manager::SetAll() {
abstr_emp::SetAll();
cout <<"please enter inChargeOf:";
cin >> inChargeOf;
}
fink::fink(const fink &f) : abstr_emp((const abstr_emp&)f)
{
reportSto = f.reportSto;
}
void fink::showAll() const {
abstr_emp::showAll();
cout << "reportSto: " << reportSto << endl;
}
void fink::SetAll() {
abstr_emp::SetAll();
cout <<"please enter reportSto:";
cin >> reportSto;
}
highfink::highfink(const highfink &hf) : abstr_emp((const abstr_emp&)hf),manager((const manager&)hf), fink((const fink&)hf)
{
}
void highfink::showAll() const {
abstr_emp::showAll();
cout << fink::ReportSto() << endl;
cout << manager::in_chargeOf() << endl;
}
void highfink::SetAll() {
abstr_emp::SetAll();
cout <<"please enter inchargeof:";
cin >> in_chargeOf();
cout << "please enter reportsto:";
cin >> ReportSto();
}
#include"abstr_emp.h"
#include<iostream>
#include<string>
using std::cout;
using std::cin;
using std::endl;
using std::string;
using std::ostream;
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", "Ogga", "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;
}