神秘博客

C++ Primer Plus [第六版]第14章编程练习题答案

这章真的好难,有点头大,关系多的绕的头疼

1

#ifndef WINEC_H_
#define WINEC_H_
#include <iostream>
#include <string>
#include <valarray>

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; }
  void setfirst(const T1 &t);
  void setsecond(const T2 &t);
  Pair(const T1 & aval, const T2 & bval) : a(aval), b(bval) { }
  Pair() {}
};
template <class T1, class T2>
void Pair<T1, T2>::setfirst(const T1 &t)
{
  a = t;
}

template <class T1, class T2>
void Pair<T1, T2>::setsecond(const T2 &t)
{
  b = t;
}

template<class T1, class T2>
T1 & Pair<T1, T2>::first()
{
  return a;
}
template<class T1, class T2>
T2 & Pair<T1, T2>::second()
{
  return b;
}


class Wine
{
private:
  typedef std::valarray<int> ArrayInt;
  typedef Pair<ArrayInt, ArrayInt> PairArray;
  std::string name;
  int year;
  PairArray years;
public:
  Wine(const char *l, int y, const int yr[], const int bot[]);
  Wine(const char *l, int y);
  void GetBottles();
  std::string Label() const;
  int sum() const;
  void Show() const;
};


#endif
#include "winec.h"

Wine::Wine(const char *l, int y, const int yr[], const int bot[])
{
  name = l;
  year = y;
  years.setfirst(ArrayInt(y));
  years.setsecond(ArrayInt(y));
  for (int i = 0; i < y; i++)
  {
    years.first()[i] = yr[i];
    years.second()[i] = bot[i];
  }
}

Wine::Wine(const char *l, int y)
{
  name = l;
  year = y;
  years.setfirst(ArrayInt(y));
  years.setsecond(ArrayInt(y));
}

void Wine::GetBottles()
{
  for (int i = 0; i < year; i++)
  {
    std::cout << "输入 " << name << " " << year << " 年的数据:\n";
    std::cout << "输入年代: ";
    std::cin >> years.first()[i];
    std::cout << "输入这一年的瓶数: ";
    std::cin >> years.second()[i];
  }
  
}

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

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

void Wine::Show() const
{
  using std::cout;
  using std::endl;
  cout << "Wine: " << name << endl;
  cout << "Year    Bottles\n";
  for (int i = 0; i < year; i++)
    cout << years.first()[i] << "    " << years.second()[i] << endl;
}
#include <iostream>
#include "winec.h"

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

  cout << "输入葡萄酒名称: ";
  char lab[50];
  cin.getline(lab, 50);
  cout << "输入多少年数据: ";
  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 mors("Gushing Grape Red", YRS, y, b);
  mors.Show();
  cout << "Total Bottles for " << mors.Label() << ": " << mors.sum() << endl;
  cout << "再见\n";

  system("pause");
  return 0;
}

2

#ifndef WINEC_H_
#define WINEC_H_
#include <iostream>
#include <string>
#include <valarray>

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


class Wine :private std::string, private PairArray
{
private:
  int count;
public:
  Wine(const char *l, int y, const int yr[], const int bot[]) :std::string(l), count(y), PairArray(ArrayInt(yr, y), ArrayInt(bot, y)) {}
  Wine(const char *l, int y) :std::string(l), count(y), PairArray(ArrayInt(y), ArrayInt(y)) {}
  void GetBottles();
  std::string Label() const;
  int sum() const;
  void Show() const;
};


#endif
#include "winec.h"


void Wine::GetBottles()
{
  for (int i = 0; i < count; i++)
  {
    std::cout << "输入 " << (const std::string &)(*this) << " " << count << " 年的数据:\n";
    std::cout << "输入年代: ";
    std::cin >> PairArray::first.operator[](i);
    std::cout << "输入这一年的瓶数: ";
    std::cin >> PairArray::second.operator[](i);
  }
  
}

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

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

void Wine::Show() const
{
  using std::cout;
  using std::endl;
  cout << "Wine: " << (const std::string &)(*this) << endl;
  cout << "Year    Bottles\n";
  for (int i = 0; i < count; i++)
    cout << PairArray::first.operator[](i) << "    " << PairArray::second.operator[](i) << endl;
}
#include <iostream>
#include "winec.h"

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

  cout << "输入葡萄酒名称: ";
  char lab[50];
  cin.getline(lab, 50);
  cout << "输入多少年数据: ";
  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 mors("Gushing Grape Red", YRS, y, b);
  mors.Show();
  cout << "Total Bottles for " << mors.Label() << ": " << mors.sum() << endl;
  cout << "再见\n";

  system("pause");
  return 0;
}

3

#ifndef QUEUETP_H_
#define QUEUETP_H_


template <typename T>
class QueueTp
{
private:
  struct Node { T *item; Node *next; };
  static const int size = 5;
  int Max;
  Node *front; //第一个
  Node *rear; //最后一个
  int count;
public:
  QueueTp(int m = size);
  ~QueueTp();
  bool isEmpty();
  bool isFull();
  bool Push(T *items);
  bool Pop();
  T *Item() const;

};

template <typename T>
T *QueueTp<T>::Item() const
{
  return front->item;
}

template <typename T>
QueueTp<T>::QueueTp(int m) :Max(m)
{
  count = 0;
  front = rear = NULL;
}

template <typename T>
QueueTp<T>::~QueueTp()
{

}

template <typename T>
bool QueueTp<T>::isEmpty()
{
  return count == 0;
}

template <typename T>
bool QueueTp<T>::isFull()
{
  return count == Max;
}

template <typename T>
bool QueueTp<T>::Push(T *items)
{
  if (isFull())
    return false;
  Node *temp = new Node;
  temp->item = items;
  temp->next = NULL;
  count++;
  if (front == NULL)
    front = temp;
  else
    rear->next = temp;
  rear = temp;
  return true;
}

template <typename T>
bool QueueTp<T>::Pop()
{
  if (isEmpty())
    return false;
  delete front->item;
  Node *temp = front;
  front = front->next;
  delete temp;
  count--;
  if (isEmpty())
    rear = NULL;
  return true;
}

#endif
#ifndef WORKER_H_
#define WORKER_H_
#include <string>

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;
};

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;
};

class Singer : virtual public Worker
{
protected:
  enum {
    other, alto, contralto, soprano,
    bass, baritone, tenor
  };
  enum { Vtypes = 7 };
  void Data() const;
  void Get();
private:
  static const 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;
};

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 & wt, int p = 0)
    : Worker(wt), Waiter(wt, p), Singer(wt) {}
  void Set();
  void Show() const;
};

#endif
#include <iostream>
#include "worker.h"
using std::cout;
using std::cin;
using std::endl;

Worker::~Worker() { }

void Worker::Data() const
{
  cout << "Name: " << fullname << endl;
  cout << "Employee ID: " << id << endl;
}

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

void Waiter::Set()
{
  cout << "Enter waiter's name: ";
  Worker::Get();
  Get();
}

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

void Waiter::Data() const
{
  cout << "Panache rating: " << panache << endl;
}

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


const 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();
}


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 << '\n';
  while (cin >> voice && (voice < 0 || voice >= Vtypes))
    cout << "Please enter a value >= 0 and < " << Vtypes << endl;
  while (cin.get() != '\n')
    continue;
}


void SingingWaiter::Data() const
{
  Singer::Data();
  Waiter::Data();
}

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();
}
#include <iostream>
#include <cstring>
#include "queuetp.h"
#include "worker.h"
const int SIZE = 3;

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

  QueueTp<Worker> last(SIZE);
  Worker *Temp = NULL;

  char choice;
  cout << "Enter the employee category:\n"
    << "w: waiter  s: singer  "
    << "t: singing waiter  q: quit\n";
  while (cin >> choice)
  {
    while (strchr("wstq", choice) == NULL)
    {
      cout << "Please enter a w, s, t, or q: ";
      cin >> choice;
    }
    if (choice == 'q')
      break;
    if (last.isFull())
    {
      cout << "队列已满...\n";
      break;
    }
    else
    {
      switch (choice)
      {
      case 'w':
        Temp = new Waiter;
        cin.get();
        Temp->Set();
        break;
      case 's':
        Temp = new Singer;
        cin.get();
        Temp->Set();
        break;
      case 't':
        Temp = new SingingWaiter;
        cin.get();
        Temp->Set();
        break;
      }
      last.Push(Temp);
    }

    cout << "Enter the employee category:\n"
      << "w: waiter  s: singer  "
      << "t: singing waiter  q: quit\n";
  }
  
  if (last.isEmpty())
    cout << "队列为空...\n";
  else
  {
    cout << "\nHere is your staff:\n";
    while (!last.isEmpty())
    {
      cout << endl;
      last.Item()->Show();
      last.Pop();
    }
  }

  
  cout << "Bye.\n";

  system("pause");
  return 0;
}

4

#ifndef PERSON_H_
#define PERSON_H_


class Person
{
private:
  char firstname[40];
  char lastname[20];
protected:
  virtual void Data() const;
  void Get();
public:
  Person(const char *f = "no name", const char *l = "no");
  virtual void Set();
  virtual ~Person();
  virtual void Show() const;

};

class Gunslinger :virtual public Person
{
private:
  double Shootingtime;
  int Pistolmark;
protected:
  void Data() const;
  void Get();
public:
  Gunslinger(const char *f = "no name", const char *l = "no", double s = 0.0, int p = 0) :Person(f, l), Shootingtime(s), Pistolmark(p) {}
  void Set();
  double Draw() const { return Shootingtime; }
  void Show() const;

};

class PokerPlayer :virtual public Person
{
public:
  PokerPlayer(const char *f = "no name", const char *l = "no") :Person(f, l) {}
  void Set();
  int Draw() const;
  void Show() const;
};

class BadDude :public Gunslinger, public PokerPlayer
{
protected:
  void Data() const;
public:
  BadDude(const char *f = "no name", const char *l = "no", double s = 0.0, int p = 0) :Person(f, l), Gunslinger(f, l, s, p) {}
  void Set();
  double Gdraw() const { return Gunslinger::Draw(); }
  int Gdraws() const { return PokerPlayer::Draw(); }
  void Show() const;
};

#endif

#include <iostream>
#include "person.h"
#include <cstring>
#include <cstdlib>

Person::Person(const char *f, const char *l)
{
  strcpy_s(firstname, 40, f);
  strcpy_s(lastname, 20, l);
}

Person::~Person()
{

}

void Person::Get()
{
  char temp[40];
  std::cout << "请输入姓氏: ";
  std::cin.getline(temp, 40);
  strcpy_s(lastname, 20, temp);
  std::cout << "请输入名字: ";
  std::cin.getline(temp, 40);
  strcpy_s(firstname, 40, temp);
}

void Person::Data() const
{
  std::cout << "姓名: ";
  std::cout << lastname << " " << firstname << std::endl;
}

void Person::Set()
{
  Get();
}

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

void Gunslinger::Data() const
{
  std::cout << "手枪刻痕: " << Pistolmark << std::endl;
  std::cout << "拔枪时间: " << Shootingtime << " s" << std::endl;
}

void Gunslinger::Get()
{
  std::cout << "请输入手枪刻痕: ";
  std::cin >> Pistolmark;
  std::cout << "请输入拔枪时间[s]: ";
  std::cin >> Shootingtime;
}

void Gunslinger::Set()
{
  Person::Get();
  Get();
}

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


int PokerPlayer::Draw() const
{
  return (rand() % 52);
}

void PokerPlayer::Set()
{
  Person::Get();
}

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

void BadDude::Data() const
{
  const char *colour[4] = { "黑桃","方片","梅花","红桃" };
  const char Poker[13][3] = { "A","2","3","4","5","6","7","8","9","10","J","Q","K" };
  std::cout << "下一张扑克牌是: " << colour[int(Gdraws() / 13)] << Poker[Gdraws() % 13] << std::endl;
}

void BadDude::Set()
{
  Person::Get();
  Gunslinger::Get();
}

void BadDude::Show() const
{
  Person::Data();
  Gunslinger::Data();
  Data();
}
#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;
  for (ct = 0; ct < SIZE; ct++)
  {
    char choice;
    cout << "输入类型:\n"
      << "a: Person \tb: Gunslinger\n"
      << "c: PokerPlayer \td: BadDude\nq: 退出\n";
    cin >> choice;
    while (strchr("abcdq", choice) == NULL)
    {
      while (cin.get() != '\n')
        continue;
      cout << "请输入 a, b, c, d, or q: ";
      cin >> choice;
    }
    if (choice == 'q')
      break;
    switch (choice)
    {
    case 'a':   
      lolas[ct] = new Person;
      break;
    case 'b':   
      lolas[ct] = new Gunslinger;
      break;
    case 'c':   
      lolas[ct] = new PokerPlayer;
      break;
    case 'd':   
      lolas[ct] = new BadDude;
      break;
    }
    cin.get();
    lolas[ct]->Set();
  }

  cout << "\n这是你的输入:\n";
  int i;
  for (i = 0; i < ct; i++)
  {
    cout << endl;
    lolas[i]->Show();
  }
  for (i = 0; i < ct; i++)
    delete lolas[i];
  cout << "Bye.\n";

  system("pause");
  return 0;
}

5

#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) :fname(fn), lname(ln), job(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() :abstr_emp() {}
  employee(const std::string &fn, const std::string &ln, const std::string &j) :abstr_emp(fn, ln, j) {}
  virtual void ShowAll() const { abstr_emp::ShowAll(); }
  virtual void SetAll() { abstr_emp::SetAll(); }
};

class manager :virtual public abstr_emp
{
private:
  int inchargeof;
protected:
  int InChargOf() const { return inchargeof; }
  int &InChargeOf() { return inchargeof; }
public:
  manager() :abstr_emp() { inchargeof = 0; }
  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() { reportsto = "no"; }
  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(const abstr_emp &e, const std::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() :abstr_emp(), manager(), fink() {}
  highfink(const std::string &fn, const std::string &ln, const std::string &j, const std::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 std::string &rpo, int ico) :abstr_emp(e), manager(e, ico), fink(e, rpo) {}
  highfink(const fink &f, int ico) :abstr_emp(f), manager(f, ico), fink(f) {}
  highfink(const manager &m, const std::string &rpo) :abstr_emp(m), manager(m), fink(m, rpo) {}
  highfink(const highfink &h) :abstr_emp(h), manager(h), fink(h) {}
  virtual void ShowAll() const;
  virtual void SetAll();
};

#endif

#include "emp.h"

abstr_emp::abstr_emp()
{
  fname = lname = job = "no";
}

void abstr_emp::ShowAll() const
{
  std::cout << "姓名: " << lname << " " << fname << std::endl;
  std::cout << "职业: " << job << std::endl;
}

void abstr_emp::SetAll()
{
  std::cout << "请输入姓氏: ";
  getline(std::cin, lname);
  std::cout << "请输入名字: ";
  getline(std::cin, fname);
  std::cout << "请输入职业: ";
  getline(std::cin, job);
}

std::ostream &operator<<(std::ostream &os, const abstr_emp &e)
{
  os << "姓名: " << e.lname << " " << e.fname << std::endl;
  os << "职业: " << e.job << std::endl;

  return os;
}

abstr_emp::~abstr_emp()
{

}


manager::manager(const manager &m) :abstr_emp(m)
{
  inchargeof = m.inchargeof;
}

void manager::ShowAll() const
{
  abstr_emp::ShowAll();
  std::cout << "职责: " << inchargeof << std::endl;
}

void manager::SetAll()
{
  abstr_emp::SetAll();
  std::cout << "请输入职责: ";
  std::cin >> inchargeof;
}

void fink::ShowAll() const
{
  abstr_emp::ShowAll();
  std::cout << "报告: " << reportsto << std::endl;
}

void fink::SetAll()
{
  abstr_emp::SetAll();
  std::cout << "请输入报告: ";
  getline(std::cin, reportsto);
}

void highfink::ShowAll() const
{
  manager::ShowAll();
  std::cout << "报告: " << fink::ReportsTo() << std::endl;
}

void highfink::SetAll()
{
  manager::SetAll();
  std::cin.get();
  std::cout << "请输入报告: ";
  getline(std::cin, fink::ReportsTo());
}
#include <iostream>
#include "emp.h"

using namespace std;

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();

  system("pause");
  return 0;
}

为什么没有定义赋值运算符?

答:所有类的数据成员,都没有包含指针,在构造函数里面也没有使用new。所以不需要。

为什么要将ShowAll和SetAll定义为虚?

答:这样就可以在使用基类指针的时候,可以根据所指对象类型正确调用函数。

为什么将abstr_emp定义为虚基类?

答:这样highfink就不会有多个abstr_emp子对象了。

为什么highfink类没有数据部分?

答:这个看类的设计,没有新的数据需要记录就没有啦。

为什么只需要一个operator<<()版本?

答:因为类继承可以默认向上兼容,基层可以直接兼容继承的类数据

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

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

答:无法替换,因为基类析构函数被设置为纯虚函数

版权说明:
点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注

觉得文章有用就请我吃包辣条吧

微信扫一扫打赏