C++ Primer Plus 第十四章答案 C++中的代码重用

简介: 只有聪明人才能看见的摘要~( ̄▽ ̄~)~

复习题

//14.6
//1
公有,北极熊是一种熊
私有,家里有厨房
公有,程序员是一种人
私有,马和驯马师的组合包含一个人
人,公有,司机是一个人
汽车,私有,司机有汽车
//2
Gloam::Gloam(int g, const char* s) : fb(s), glip(g) {}
Gloam::Gloam(int g, const Frabjous& f) : fb(f), glip(g) {}
void Gloam::tell() {
  fb.tell();
  std::cout << "glib: " << glib >> endl;
}
//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();
  std::cout << "glib: " << glib >> endl;
}
//4
class Stack<Worker*> {
private:
  enum { MAX = 10 };
  Worker* items[MAX];
  int top;
public:
  Stack();
  bool isempty();
  bool isfull();
  bool push()(const Workser*& item);
  bool pop(Worker*& item);
};
//5
ArrayTP<string>arr_str;
StackTP<ArrayTP<double>>sck_arr_db;
ArrayTP<StackTP<Worker*>>arr_stk_workerp;
4个
//6
如果两条继承路线有相同的祖先,则类中将包含祖先成员的两个拷贝
将祖先类作为虚基类可以解决这种问题

image.gif

编程练习

第一题

#pragma once
//wine.h
#include<valarray>
#include<string>
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() {}
};
class Wine {
private:
  typedef std::valarray<int> ArrayInt;
  typedef Pair<ArrayInt, ArrayInt> PairArray;
  std::string label;
  PairArray pair;
  int yr_num;
public:
  Wine() :label("None"), yr_num(0),pair() {};
  Wine(const char* l, int y, const int yr[], const int bot[]);
  Wine(const char* l, int y);
  void GetBottles();
  const std::string& Label()const;
  int sum()const;
  void show()const;
};
//wine.cpp
#include<iostream>
#include"wine.h"
using namespace std;
Wine::Wine(const char* l, int y, const int yr[], const int bot[])
  :label(l), yr_num(y) {
  ArrayInt a(y);
  ArrayInt b(y);
  for (int i = 0; i < y; i++) {
    a[i] = yr[i];
    b[i] = bot[i];
  }
  pair.first() = a;
  pair.second() = b;
}
Wine::Wine(const char* l, int y) :label(l), yr_num(y) {
  ArrayInt a(y);
  ArrayInt b(y);
  for (int i = 0; i < y; i++) {
    a[i] = 0;
    b[i] = 0;
  }
  pair.first() = a;
  pair.second() = b;
}
void Wine::GetBottles() {
  ArrayInt a(yr_num);
  ArrayInt b(yr_num);
  cout << "Enter " << label << " data for " << yr_num << " year(s):" << endl;
  for (int i = 0; i < yr_num; i++) {
    cout << "Enter year: ";
    cin >> a[i];
    cout << "Enter bottles for that years: ";
    cin >> b[i];
  }
  pair.first() = a;
  pair.second() = b;
}
const string& Wine::Label()const {
  return label;
}
int Wine::sum()const {
  int sum = 0;
  for (int i = 0; i < yr_num; i++)
    sum += pair.second()[i];
  return sum;
}
void Wine::show()const {
  cout << "Wine: " << label << endl;
  cout << "\tyear\tBottles" << endl;
  for (int i = 0; i < yr_num; i++)
    cout << "\t" << pair.first()[i] << "\t" << pair.second()[i] << endl;
}
template<class T1, class T2>
T1& Pair<T1, T2>::first() {
  return a;
}
template<class T1, class T2>
T2& Pair<T1, T2>::second() {
  return b;
}
//main.cpp
#include"wine.h"
#include<iostream>
using namespace std;
int main() {
  cout << "Enter name of wine: ";
  char lab[50];
  cin.getline(lab, 50);
  cout << "Enter number of years:";
  int years;
  cin >> years;
  Wine holding(lab, years);
  holding.GetBottles();
  holding.show();
  const int YEARS = 3;
  int y[YEARS] = { 1993,1995,1998 };
  int b[YEARS] = { 48,60,72 };
  Wine more("Gushing Grape Red", YEARS, y, b);
  more.show();
  cout << "Total bottles for " << more.Label()
    << ": " << more.sum() << endl;
  cout << "Bye!";
  return 0;
}

image.gif

第二题

测试程序不变,因此只给出类声明和方法定义

#pragma once
//wine.h
#include<valarray>
#include<string>
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() {}
};
typedef std::valarray<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;
class Wine :std::string,Pair<ArrayInt, ArrayInt>{
private:
  int yr_num;
public:
  Wine() :std::string("None"), yr_num(0),Pair() {};
  Wine(const char* l, int y, const int yr[], const int bot[]);
  Wine(const char* l, int y);
  void GetBottles();
  const std::string& Label()const;
  int sum()const;
  void show()const;
};
//wine.cpp
#include<iostream>
#include"wine.h"
using namespace std;
Wine::Wine(const char* l, int y, const int yr[], const int bot[])
  :string(l), yr_num(y) {
  ArrayInt a(y);
  ArrayInt b(y);
  for (int i = 0; i < y; i++) {
    a[i] = yr[i];
    b[i] = bot[i];
  }
  Pair::first() = a;
  Pair::second() = b;
}
Wine::Wine(const char* l, int y) :string(l), yr_num(y) {
  ArrayInt a(y);
  ArrayInt b(y);
  for (int i = 0; i < y; i++) {
    a[i] = 0;
    b[i] = 0;
  }
  Pair::first() = a;
  Pair::second() = b;
}
void Wine::GetBottles() {
  ArrayInt a(yr_num);
  ArrayInt b(yr_num);
  cout << "Enter " << (const string&)*this << " data for " << yr_num << " year(s):" << endl;
  for (int i = 0; i < yr_num; i++) {
    cout << "Enter year: ";
    cin >> a[i];
    cout << "Enter bottles for that years: ";
    cin >> b[i];
  }
  Pair::first() = a;
  Pair::second() = b;
}
const string& Wine::Label()const {
  return (const string&)*this;
}
int Wine::sum()const {
  int sum = 0;
  for (int i = 0; i < yr_num; i++)
    sum += Pair::second()[i];
  return sum;
}
void Wine::show()const {
  cout << "Wine: " << (const string&)*this << endl;
  cout << "\tyear\tBottles" << endl;
  for (int i = 0; i < yr_num; i++)
    cout << "\t" << Pair::first()[i] << "\t" << Pair::second()[i] << endl;
}
template<class T1, class T2>
T1& Pair<T1, T2>::first() {
  return a;
}
template<class T1, class T2>
T2& Pair<T1, T2>::second() {
  return b;
}

image.gif

第三题

大坑,因为书上只说了一遍,没有重复三遍以上(狗头)因此我压根没注意到。

因为模板类和模板函数只有在使用时才会实例化。当模板被使用时,编译器需要函数的所有代码,来用合适的类型去构建正确的函数,而如果函数的实现写在一个独立的源文件中,这些文件是不可见的,因此会出错。LNK2019。

总之队列的模板声明和函数定义放在一起。

#pragma once
//worker.h
#include<string>
class Worker {
private:
  std::string fullname;
  long id;
protected:
  virtual void Data()const;
  virtual void Get();
public:
  Worker() :fullname("no name"), 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 {
  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& w, int p = 0) :Worker(w), 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 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& w, int v = other)
    :Worker(w), voice(v) {}
  void Set();
  void Show()const;
};
class SW :public Singer, public Waiter {
protected:
  void Data()const;
  void Get();
public:
  SW() {}
  SW(const std::string& s, long n, int p = 0, int v = other)
    :Worker(s, n), Waiter(s, n, p), Singer(s, n, v) {}
  SW(const Worker& w, int p = 0, int v = other)
    :Worker(w), Waiter(w, p), Singer(w, v) {}
  SW(const Worker& w, int p = 0)
    :Worker(w), Waiter(w, p), Singer(w) {}
  void Set();
  void Show()const;
};
//worker.cpp
#include<iostream>
#include"worker.h"
using namespace std;
//Worker methods
Worker::~Worker() {}
void Worker::Get() {
  getline(cin, fullname);
  cout << "Enter worker's ID: ";
  cin >> id;
  while (cin.get() != '\n')
    continue;
}
void Worker::Data()const {
  cout << "Name: " << fullname << endl;
  cout << "Employee ID: " << id << endl;
}
//Waiter methods
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;
}
//Singer methods
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::Data()const {
  cout << "Vocla range: " << pv[voice] << endl;
}
void Singer::Show()const {
  cout << "Category: singer\n";
  Worker::Data();
  Data();
}
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 << endl;
  cin >> voice;
  while (cin.get() != '\n')
    continue;
}
//SW methods
void SW::Data()const {
  Singer::Data();
  Waiter::Data();
}
void SW::Get() {
  Waiter:: Get();
  Singer::Get();
}
void SW::Set() {
  cout << "Enter singing waiter's name: ";
  Worker::Get();
  Get();
}
void SW::Show()const {
  cout << "Category: singing waiter\n";
  Worker::Data();
  Data();
}
//queuetpyue.cpp
//队列的设计参考第12章程序清单12.10
//因为模板类和模板函数只有在使用时才会实例化。
//当模板被使用时,编译器需要函数的所有代码,来用合适的类型去构建正确的函数,
//而如果函数的实现写在一个独立的源文件中,这些文件是不可见的,因此会出错。
template<class T>
class QueueTP {
  enum { MAX = 10 };
  struct Node { T item; Node* next; };
  Node* front;
  Node* rear;
  int items;
  const int qsize = MAX;
  QueueTP<T>(const QueueTP<T>& q) : qsize(0) {}
  QueueTP<T>& operator=(const QueueTP<T>& q) { return *this; }
public:
  QueueTP(int qs = MAX);
  ~QueueTP();
  bool isempty()const;
  bool isfull()const;
  int queuecount()const { return items; }
  bool enqueue(const T& item);
  bool dequeue(T& item);
};
template<class T>
QueueTP<T>::QueueTP(int qs) : qsize(qs) {
  front = rear = nullptr;
  items = 0;
}
template<class T>
QueueTP<T>::~QueueTP() {
  Node* temp;
  while (front != nullptr) {
    temp = front;
    front = front->next;
    delete temp;
  }
}
template<class T>
bool QueueTP<T>::isempty()const {
  return items == 0;
}
template<class T>
bool QueueTP<T>::isfull()const {
  return items == qsize;
}
template<class T>
bool QueueTP<T>::enqueue(const T& item) {
  if (isfull())
    return false;
  Node* add = new Node;
  add->next = nullptr;
  add->item = item;
  items++;
  if (front == nullptr)
    front = add;
  else
    rear->next = add;
  rear = add;
  return true;
}
template<class T>
bool QueueTP<T>::dequeue(T& item) {
  if (front == nullptr)
    return false;
  item = front->item;
  items--;
  Node* temp = front;
  front = front->next;
  delete temp;
  if (items == 0)
    rear = nullptr;
  return true;
}
//main.cpp
#include"queuetpyue.h"
#include"worker.h"
#include<iostream>
#include<cstring>
using namespace std;
const int SIZE = 5;
int main() {
  QueueTP<Worker*> qw(SIZE);
  Worker* lolas[SIZE];
  int ct;
  for (ct = 0; ct < SIZE; ct++) {
    char choice;
    cout << "Enter the employee category:\n"
      << "w: waiter   s: singer   "
      << "t: Singing Waiter   q: quit\n";
    cin >> choice;
    while (strchr("wstq", choice) == nullptr) {
      cout << "Please enter a w, s, t or q: ";
      cin >> choice;
    }
    if (choice == 'q')
      break;
    switch (choice) {
    case'w':lolas[ct]=new Waiter; break;
    case's':lolas[ct]=new Singer; break;
    case't':lolas[ct]=new SW; break;
    }
    cin.get();
    lolas[ct]->Set();
    cout << "Enqueue! #" << ct << endl;
    lolas[ct]->Show();
    qw.enqueue(lolas[ct]);
  }
  cout << "\nHere is your staff(dequeue):\n";
  for (int i = 0; i < ct; i++) {
    qw.dequeue(lolas[i]);
    lolas[i]->Show();
    delete lolas[i];
  }
  cout << "Bye!\n";
  return 0;
}

image.gif

第四题

//abc.h
#include<string>
using std::string;
class Person {
  string fname;
  string lname;
protected:
  virtual void GetData();
public:
  Person() :fname("no name"), lname() {}
  Person(string& f, string& l) :fname(f), lname(l) {}
  virtual ~Person() {}
  virtual void Show();
  virtual void Set();
};
class Gunslinger :virtual public Person {
  double draw;
  int kehen;
protected:
  void GetData();
public:
  Gunslinger() :Person(), draw(0.0), kehen(0) {}
  Gunslinger(string& f, string& l, double time, int kh)
    :Person(f, l), draw(time), kehen(kh) {}
  Gunslinger(Person& p, double time, int kh)
    :Person(p), draw(time), kehen(kh) {}
  double Draw() { return draw; }
  void Show();
  void Set();
};
class PokerPlayer :virtual public Person {
  int puke;
protected:
  void GetData();
public:
  PokerPlayer() :Person(), puke(1) {}
  PokerPlayer(string& f, string& l, int pk) :Person(f, l), puke(pk) {}
  PokerPlayer(Person& p, int pk) :Person(p), puke(pk) {}
  int Draw();
  void Show();
  void Set();
};
class BadDude :public Gunslinger, public PokerPlayer {
protected:
  void GetData();
public:
  BadDude() :Person(), Gunslinger(), PokerPlayer() {}
  BadDude(string& f, string& l, double time, int kh)
    :Person(f, l), Gunslinger(f, l, time, kh) {}
  BadDude(Person& p, double time, int kh)
    :Person(p), Gunslinger(p, time, kh) {}
  double Gdraw() { Gunslinger::Draw(); }
  int Cdraw() { PokerPlayer::Draw(); }
  void Show();
  void Set();
};
//abc.cpp
#include<iostream>
#include"abc.h"
#include<cstdlib>
#include<ctime>
using namespace std;
void Person::GetData() {
  cout << "输入名和姓:";
  cin >> fname >> lname;
}
void Person::Show() {
  cout << "此人的名字:" << lname
    << " " << fname << endl;
}
void Person::Set() {
  GetData();
}
void Gunslinger::GetData() {
  cout << "输入拔枪时间(double):";
  cin >> draw;
  cout << "输入刻痕数(int):";
  cin >> kehen;
}
void Gunslinger::Show() {
  Person::Show();
  cout << "拔枪时间:" << draw << endl;
  cout << "刻痕数:" << kehen << endl;
}
void Gunslinger::Set() {
  Person::GetData();
  GetData();
}
void PokerPlayer::GetData() {
  cout << "输入扑克牌数(1 to 53):";
  cin >> puke;
}
int PokerPlayer::Draw() {
  srand(time(0));
  return rand() % (53) + 1;
}
void PokerPlayer::Show() {
  Person::Show();
  cout << "扑克牌:" << puke << endl;
}
void PokerPlayer::Set() {
  Person::GetData();
  GetData();
}
void BadDude::GetData() {
  Person::GetData();
  Gunslinger::GetData();
  PokerPlayer::GetData();
}
void BadDude::Show() {
  Gunslinger::Show();
  cout << "扑克牌:" << PokerPlayer::Draw();
}
void BadDude::Set() {
  GetData();
}
//main.cpp
#include"abc.h"
#include<iostream>
#include<cstring>
using namespace std;
const int SIZE = 5;
int main() {
  Person* lolas[SIZE];
  int ct;
  for (ct = 0; ct < SIZE; ct++) {
    char choice;
    cout << "Enter the person's category:\n"
      << "a: Person   b: Gunslinger   "
      << "c: PokerPlayer   " << endl
      << "d:BadDude    q: quit\n";
    cin >> choice;
    while (strchr("abcdq", choice) == nullptr) {
      cout << "Please enter 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 << endl;
  }
  cout << "\nHere are the peoples:\n";
  for (int i = 0; i < ct; i++) {
    cout << "#" << i << endl;
    lolas[i]->Show();
    cout << endl;
    delete lolas[i];
  }
  cout << "Bye!\n";
  return 0;
}

image.gif

第五题

//emp.h
#include<iostream>
#include<string>
using namespace std;
class abstr_emp {
  string fname;
  string lname;
  string job;
public:
  abstr_emp() :fname("no"), lname("name"), job("no job") {}
  abstr_emp(const string& fn, const string& ln, const string& j)
    :fname(fn), lname(ln), job(j) {}
  //此处const表示此函数不会修改传递的值
  //函数后的const表示不会修改类的数据成员
  virtual void ShowAll()const;
  virtual void SetAll();                            
  friend ostream& operator<<(ostream& os, const abstr_emp& a);
  virtual ~abstr_emp() = 0 {}
};
class employee :public abstr_emp {
public:
  employee() :abstr_emp() {}
  employee(const string& fn, const string& ln, const string& j)
    :abstr_emp(fn, ln, j) {}
  void ShowAll()const;
  void SetAll();
};
class manager :virtual public abstr_emp {
private:
  int inchargeof;
protected:
  int Inchargeof()const { return inchargeof; }//output
  int& Inchargeof() { return inchargeof; }//input
  //只读(const)和非只读函数可以形成重载关系.此时,对于只读对象,只能调用只读函数
  //而非只读对象会优先选择非只读函数.
public:
  manager() :abstr_emp(), inchargeof(0) {}
  manager(const string& fn, const string& ln, const string& j,
    int ico = 0) :abstr_emp(fn, ln, j), inchargeof(ico) {}
  manager(const abstr_emp& a, int ico = 0) :abstr_emp(a), 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 {
  string reportsto;
protected:
  const string Reportsto()const { return reportsto; }
  string& Reportsto() { return reportsto; }
public:
  fink() :abstr_emp(), reportsto("???") {}
  fink(const string& fn, const string& ln, const string& j,
    const string& rt) :abstr_emp(fn, ln, j), reportsto(rt) {}
  fink(const abstr_emp& e, const string& rt) :abstr_emp(e), reportsto(rt) {}
  fink(const fink& f) :abstr_emp(f), reportsto(f.reportsto) {}
  virtual void ShowAll()const;
  virtual void SetAll();
};
class highfink :public manager, public fink {
public:
  highfink() :abstr_emp(), manager(), fink() {}
  highfink(const string& fn, const string& ln, const string& j,
    const string& rt, int ico)
    :abstr_emp(fn, ln, j), manager(fn, ln, j, ico), fink(fn, ln, j, rt) {}
  highfink(const abstr_emp& a, const string& rt, int ico)
    :abstr_emp(a), manager(a, ico), fink(a, rt) {}
  highfink(const fink& f, int ico)
    :abstr_emp(f), manager(f, ico), fink(f) {}
  highfink(const manager& m, const string& rt)
    :abstr_emp(m), manager(m), fink(m, rt) {}
  highfink(const highfink& h)
    :abstr_emp(h), manager(h), fink(h) {}
  virtual void ShowAll()const;
  virtual void SetAll();
};
//emp.cpp
#include"emp.h"
using namespace std;
void abstr_emp::ShowAll()const {
  cout << "Name: " << fname << " " << lname << endl;
  cout << "job: " << job << endl;
}
void abstr_emp::SetAll() {
  cout << "Enter the data:\n" << "first name: ";
  cin >> fname;
  cout << "lastname: ";
  cin >> lname;
  cout << "job: ";
  cin >> job;
}
ostream& operator<<(ostream& os, const abstr_emp& a) {
  os << a.fname << " " << a.lname << endl;
  return os;
}
void employee::ShowAll()const {
  abstr_emp::ShowAll();
}
void employee::SetAll() {
  abstr_emp::SetAll();
}
void manager::ShowAll()const {
  abstr_emp::ShowAll();
  cout << "In charge of: " << inchargeof << endl;
}
void manager::SetAll() {
  abstr_emp::SetAll();
  cout << "in charge of: ";
  cin >> inchargeof;
}
void fink::ShowAll()const {
  abstr_emp::ShowAll();
  cout << "reports to: " << reportsto << endl;
}
void fink::SetAll() {
  abstr_emp::SetAll();
  cout << "reports to: ";
  cin >> reportsto;
}
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 << "in charge of: ";
  cin >> manager::Inchargeof();
  cout << "reports to: ";
  cin >> fink::Reportsto();
}
//main.cpp
#include"emp.h"
using namespace std;
#include<iostream>
int main() {
  employee em("Trip", "Harris", "Thumper");
  cout << em << endl;
  em.ShowAll();
  cout << endl;
  manager ma("Amorphia", "Spindragon", "Nuancer", 5);
  cout << ma << endl;
  ma.ShowAll();
  cout << endl;
  fink fi("Matt", "Oggs", "Oiler", "Juno Barr");
  cout << fi << endl;
  fi.ShowAll();
  cout << endl;
  highfink hf(ma, "Curly Kew");
  hf.ShowAll();
  cout << endl;
  cout << "Press a key for next phase:\n";
  cin.get();
  highfink hf2;
  hf2.SetAll();
  cout << endl;
  cout << "Using an abstr_emp* pointer:\n\n";
  abstr_emp* tri[4] = { &em,&fi,&hf,&hf2 };
  for (int i = 0; i < 4; i++) {
    tri[i]->ShowAll();
    cout << endl;
  }
  return 0;
}

image.gif

a:没有用到指针和new分配内存,因此默认赋值运算符使用的浅拷贝可以满足需要,不需要自己定义完成深拷贝

b:定义为虚表示接下来会在派生类重新定义它们,在使用基类指针表示派生类的时候,可以正确调用对象的函数

c:以虚基类继承时,MI(多重继承)就不会继承多个相同的对象,在MI时,继承的类中,有相同祖先的所有继承虚基类的类产生一个祖先对象,继承的不是虚基类的各产生一个祖先对象

d:所有需要的数据已经在继承的类中包含

e:此题需要的<<输出均为输出名字即可,abstr_emp的友元可供派生类使用,足以满足要求,如果题目要求使用<<时输出不同的信息,自然可以在每个类分别定义

f:实际上因为基类早已被定义为抽象类,因此不允许使用抽象类数组,如果去掉析构的=0,那么可以运行,但是显然数组的四个成员会被截留成基类,也就是只剩下基类数据,调用ShowAll()也是调用基类的ShowAll(),只显示name和job

目录
相关文章
|
6天前
|
C语言 C++ 开发者
深入探索C++:特性、代码实践及流程图解析
深入探索C++:特性、代码实践及流程图解析
|
2月前
|
自然语言处理 算法 前端开发
C++与Doxygen:精通代码文档化之道
C++与Doxygen:精通代码文档化之道
53 0
|
29天前
|
IDE Java Linux
【CMake】CMake构建C++代码(一)
【CMake】CMake构建C++代码(一)
|
29天前
|
C++ 计算机视觉 Windows
【C++】由于找不到xxx.dll,无法继续执行代码,重新安装程序可能会解决此问题。(解决办法)
【C++】由于找不到xxx.dll,无法继续执行代码,重新安装程序可能会解决此问题。(解决办法)
|
1天前
|
C++
【期末不挂科-C++考前速过系列P6】大二C++实验作业-模板(4道代码题)【解析,注释】
【期末不挂科-C++考前速过系列P6】大二C++实验作业-模板(4道代码题)【解析,注释】
【期末不挂科-C++考前速过系列P6】大二C++实验作业-模板(4道代码题)【解析,注释】
|
1天前
|
Serverless C++ 容器
【期末不挂科-C++考前速过系列P5】大二C++实验作业-多态性(3道代码题)【解析,注释】
【期末不挂科-C++考前速过系列P5】大二C++实验作业-多态性(3道代码题)【解析,注释】
|
1天前
|
C++ 芯片
【期末不挂科-C++考前速过系列P4】大二C++实验作业-继承和派生(3道代码题)【解析,注释】
【期末不挂科-C++考前速过系列P4】大二C++实验作业-继承和派生(3道代码题)【解析,注释】
|
1天前
|
编译器 C++
【期末不挂科-C++考前速过系列P3】大二C++第3次过程考核(20道选择题&12道判断题&2道代码题)【解析,注释】
【期末不挂科-C++考前速过系列P3】大二C++第3次过程考核(20道选择题&12道判断题&2道代码题)【解析,注释】
|
1天前
|
C++
【期末不挂科-C++考前速过系列P2】大二C++第2次过程考核(20道选择题&10道判断题&3道代码题)【解析,注释】
【期末不挂科-C++考前速过系列P2】大二C++第2次过程考核(20道选择题&10道判断题&3道代码题)【解析,注释】
|
1天前
|
存储 数据安全/隐私保护 C++
【期末不挂科-C++考前速过系列P1】大二C++第1次过程考核(3道简述题&7道代码题)【解析,注释】
【期末不挂科-C++考前速过系列P1】大二C++第1次过程考核(3道简述题&7道代码题)【解析,注释】