神秘博客

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

1

#ifndef CD_H_
#define CD_H_

class Cd
{
private:
  char performers[50];  //歌手
  char label[20];   //公司
  int selections;  //选集
  double playtime;  //Cd时长
public:
  Cd(const char *s1, const char *s2, const int &n, const double x);
  Cd(const Cd &d);
  Cd();
  virtual ~Cd();
  virtual void Report() const;
  Cd &operator=(const Cd &d);
};

class Classic :public Cd
{
private:
  char MainWorks[200];  //主要作品
public:
  Classic(const char *s, const char *s1, const char *s2, const int &n, const double x);
  Classic();
  virtual void Report() const;
  Classic &operator=(const Classic &d);
};

#endif
#include <cstring>
#include <iostream>
#include "cd.h"

Cd::Cd(const char *s1, const char *s2, const int &n, const double x)
{
  strcpy_s(performers, 50, s1);
  strcpy_s(label, 20, s2);
  selections = n;
  playtime = x;
}

Cd::Cd(const Cd &d)
{
  strcpy_s(performers, 50, d.performers);
  strcpy_s(label, 20, d.label);
  selections = d.selections;
  playtime = d.playtime;
}

Cd::Cd()
{
  performers[0] = '\0';
  label[0] = '\0';
  selections = 0;
  playtime = 0;
}

Cd::~Cd()
{

}

void Cd::Report() const
{
  using std::cout;
  using std::endl;
  cout << "歌手: " << performers << endl;
  cout << "公司: " << label << endl;
  cout << "选集: " << selections << endl;
  cout << "Cd时长: " << playtime << endl;
}

Cd &Cd::operator=(const Cd &d)
{
  if (this == &d)
    return *this;
  strcpy_s(performers, 50, d.performers);
  strcpy_s(label, 20, d.label);
  selections = d.selections;
  playtime = d.playtime;
  return *this;
}

Classic::Classic(const char *s, const char *s1, const char *s2, const int &n, const double x) :Cd(s1, s2, n, x)
{
  strcpy_s(MainWorks, 200, s);
}

Classic::Classic() :Cd()
{
  MainWorks[0] = '\0';
}

void Classic::Report() const
{
  Cd::Report();
  std::cout << "主要作品: " << MainWorks << std::endl;
}

Classic &Classic::operator=(const Classic &d)
{
  if (this == &d)
    return *this;
  Cd::operator=(d);
  strcpy_s(MainWorks, 200, d.MainWorks);
  return *this;
}
#include <iostream>
#include "cd.h"

using namespace std;
void Bravo(const Cd &disk);

int main()
{
  Cd c1("Beatles", "Capitol", 14, 35.5);
  Classic c2 = Classic("Piano Sonata in Bflat, Fantasia in C", "Alfred Brendel", "Philips", 2, 57.17);
  Cd *pcd = &c1;

  std::cout << "Using object directly:\n";
  c1.Report();
  cout.put('\n');
  c2.Report();
  cout.put('\n');
  std::cout << "Using type cd *pointer to object:\n";
  pcd->Report();
  cout.put('\n');
  pcd = &c2;
  pcd->Report();
  cout.put('\n');
  cout << "Calling a function with a Cd reference argument:\n";
  Bravo(c1);
  cout.put('\n');
  Bravo(c2);
  cout.put('\n');
  std::cout << "Testing assignment: \n";
  Classic copy;
  copy = c2;
  copy.Report();
  cout.put('\n');
  system("pause");
  return 0;
}

void Bravo(const Cd &disk)
{
  disk.Report();
}

2

#ifndef CD_H_
#define CD_H_

class Cd
{
private:
  char *performers;  //歌手
  char *label;   //公司
  int selections;  //选集
  double playtime;  //Cd时长
public:
  Cd(const char *s1, const char *s2, const int &n, const double x);
  Cd(const Cd &d);
  Cd();
  virtual ~Cd();
  virtual void Report() const;
  Cd &operator=(const Cd &d);
};

class Classic :public Cd
{
private:
  char *MainWorks;  //主要作品
public:
  Classic(const char *s, const char *s1, const char *s2, const int &n, const double x);
  Classic();
  ~Classic();
  virtual void Report() const;
  Classic &operator=(const Classic &d);
};

#endif
#include <cstring>
#include <iostream>
#include "cd.h"

Cd::Cd(const char *s1, const char *s2, const int &n, const double x)
{
  performers = new char[strlen(s1) + 1];
  strcpy_s(performers, strlen(s1) + 1, s1);
  label = new char[strlen(s2) + 1];
  strcpy_s(label, strlen(s2) + 1, s2);
  selections = n;
  playtime = x;
}

Cd::Cd(const Cd &d)
{
  performers = new char[strlen(d.performers) + 1];
  strcpy_s(performers, strlen(d.performers) + 1, d.performers);
  label = new char[strlen(d.performers) + 1];
  strcpy_s(label, strlen(d.label) + 1, d.label);
  selections = d.selections;
  playtime = d.playtime;
}

Cd::Cd()
{
  performers = new char[1];
  performers[0] = '\0';
  label = new char[1];
  label[0] = '\0';
  selections = 0;
  playtime = 0;
}

Cd::~Cd()
{
  delete[] performers;
  delete[] label;
}

void Cd::Report() const
{
  using std::cout;
  using std::endl;
  cout << "歌手: " << performers << endl;
  cout << "公司: " << label << endl;
  cout << "选集: " << selections << endl;
  cout << "Cd时长: " << playtime << endl;
}

Cd &Cd::operator=(const Cd &d)
{
  if (this == &d)
    return *this;
  delete[] performers;
  performers = new char[strlen(d.performers) + 1];
  strcpy_s(performers, strlen(d.performers) + 1, d.performers);
  delete[] label;
  label = new char[strlen(d.performers) + 1];
  strcpy_s(label, strlen(d.label) + 1, d.label);
  selections = d.selections;
  playtime = d.playtime;
  return *this;
}

Classic::Classic(const char *s, const char *s1, const char *s2, const int &n, const double x) :Cd(s1, s2, n, x)
{
  MainWorks = new char[strlen(s) + 1];
  strcpy_s(MainWorks, strlen(s) + 1, s);
}

Classic::Classic() :Cd()
{
  MainWorks = new char[1];
  MainWorks[0] = '\0';
}

void Classic::Report() const
{
  Cd::Report();
  std::cout << "主要作品: " << MainWorks << std::endl;
}

Classic &Classic::operator=(const Classic &d)
{
  if (this == &d)
    return *this;
  Cd::operator=(d);
  delete[] MainWorks;
  MainWorks = new char[strlen(d.MainWorks) + 1];
  strcpy_s(MainWorks, strlen(d.MainWorks) + 1, d.MainWorks);
  return *this;
}

Classic::~Classic()
{
  delete[] MainWorks;
}
#include <iostream>
#include "cd.h"

using namespace std;
void Bravo(const Cd &disk);

int main()
{
  Cd c1("Beatles", "Capitol", 14, 35.5);
  Classic c2 = Classic("Piano Sonata in Bflat, Fantasia in C", "Alfred Brendel", "Philips", 2, 57.17);
  Cd *pcd = &c1;

  std::cout << "Using object directly:\n";
  c1.Report();
  cout.put('\n');
  c2.Report();
  cout.put('\n');
  std::cout << "Using type cd *pointer to object:\n";
  pcd->Report();
  cout.put('\n');
  pcd = &c2;
  pcd->Report();
  cout.put('\n');
  cout << "Calling a function with a Cd reference argument:\n";
  Bravo(c1);
  cout.put('\n');
  Bravo(c2);
  cout.put('\n');
  std::cout << "Testing assignment: \n";
  Classic copy;
  copy = c2;
  copy.Report();
  cout.put('\n');
  system("pause");
  return 0;
}

void Bravo(const Cd &disk)
{
  disk.Report();
}

3

#ifndef DMA_H_
#define DMA_H_

class Abc
{
private:
  char *label;  //字体
protected:
  char *relabel() const;
public:
  Abc(const char *l = "null");
  Abc(const Abc &rs);
  virtual ~Abc();
  Abc &operator=(const Abc &rs);
  virtual void Show() const = 0;
};


class baseDMA :public Abc
{
private:
  int rating;  //大小
public:
  baseDMA(int r = 0, const char *l = "null");
  baseDMA(const baseDMA &rs);
  ~baseDMA();
  baseDMA &operator=(const baseDMA &rs);
  virtual void Show() const;
};

class lacksDMA :public Abc
{
private:
  enum { COL_LEN = 40 };
  char color[COL_LEN];  //颜色
public:
  lacksDMA(const char *c = "blank", const char *l = "null");
  lacksDMA(const lacksDMA &rs);
  virtual void Show() const;
};

class hasDMA :public Abc
{
private:
  char *style;  //风格
public:
  hasDMA(const char *s = "node", const char *l = "null");
  hasDMA(const hasDMA &hs);
  ~hasDMA();
  hasDMA &operator=(const hasDMA &rs);
  virtual void Show() const;
};


#endif
#include <cstring>
#include <iostream>
#include "dma.h"

Abc::Abc(const char *l)
{
  label = new char[strlen(l) + 1];
  strcpy_s(label, strlen(l) + 1, l);
}

Abc::Abc(const Abc &rs)
{
  label = new char[strlen(rs.label) + 1];
  strcpy_s(label, strlen(rs.label) + 1, rs.label);
}

char *Abc::relabel() const
{
  return label;
}

Abc::~Abc()
{
  delete[] label;
}

Abc &Abc::operator=(const Abc &rs)
{
  if (this == &rs)
    return *this;
  delete[] label;
  label = new char[strlen(rs.label) + 1];
  strcpy_s(label, strlen(rs.label) + 1, rs.label);
  return *this;
}


baseDMA::baseDMA(int r, const char *l) :Abc(l)
{
  rating = r;
}

baseDMA::baseDMA(const baseDMA &rs) : Abc(rs)
{
  rating = rs.rating;
}

baseDMA::~baseDMA()
{
}

baseDMA &baseDMA::operator=(const baseDMA &rs)
{
  if (this == &rs)
    return *this;
  Abc::operator=(rs);
  rating = rs.rating;
  return *this;
}

void baseDMA::Show() const
{
  std::cout << "字体: " << relabel() << std::endl;
  std::cout << "大小: " << rating << std::endl;
}

lacksDMA::lacksDMA(const char *c, const char *l) :Abc(l)
{
  strncpy_s(color, c, COL_LEN - 1);
  color[COL_LEN - 1] = '\0';
}

lacksDMA::lacksDMA(const lacksDMA &rs) :Abc(rs)
{
  strncpy_s(color, rs.color, COL_LEN - 1);
  color[COL_LEN - 1] = '\0';
}

void lacksDMA::Show() const
{
  std::cout << "字体: " << relabel() << std::endl;
    std::cout << "颜色: " << color << std::endl;
}

hasDMA::hasDMA(const char *s, const char *l) :Abc(l)
{
  style = new char[strlen(s) + 1];
  strcpy_s(style, strlen(s) + 1, s);
}

hasDMA::hasDMA(const hasDMA &hs) :Abc(hs)
{
  style = new char[strlen(hs.style) + 1];
  strcpy_s(style, strlen(hs.style) + 1, hs.style);
}

hasDMA::~hasDMA()
{
  delete[] style;
}

hasDMA &hasDMA::operator=(const hasDMA &rs)
{
  if (this == &rs)
    return *this;
  Abc::operator=(rs);
  delete[] style;
  style = new char[strlen(rs.style) + 1];
  strcpy_s(style, strlen(rs.style) + 1, rs.style);
  return *this;
}

void hasDMA::Show() const
{
  std::cout << "字体: " << relabel() << std::endl;
  std::cout << "风格: " << style << std::endl;
}
#include <iostream>
#include "dma.h"
#define CLIENTS 3
int main()
{
  using namespace std;

  Abc *list[CLIENTS];
  char temp[40]; //字体
  int tempsize;  //大小
  char tempcolor[40];  //颜色
  char tempstyle[40];  //风格
  char kind;  //选项

  for (int i = 0; i < CLIENTS; i++)
  {
    cout << "输入字体: ";
    cin.getline(temp, 40);
    cout << "输入 1 表示 baseDMA, 输入 2 表示 lacksDMA, 输入 3 表示 hasDMA: ";
    while (cin >> kind && (kind != '1' && kind != '2'&&kind != '3'))
    {
      cout << "输入 1 - 3: ";
      while (cin.get() != '\n')
        continue;
    }
    if (kind == '1')
    {
      cout << "输入大小: ";
      cin >> tempsize;
      list[i] = new baseDMA(tempsize, temp);
      while (cin.get() != '\n')
        continue;
    }
    else if (kind == '2')
    {
      cin.get();
      cout << "输入颜色: ";
      cin.getline(tempcolor, 40);
      list[i] = new lacksDMA(tempcolor, temp);
    }
    else
    {
      cin.get();
      cout << "输入风格: ";
      cin.getline(tempstyle, 40);
      list[i] = new hasDMA(tempstyle, temp);
    }
    cout.put('\n');
  }
  cout << endl;
  for (int i = 0; i < CLIENTS; i++)
  {
    list[i]->Show();
    cout << endl;
  }

  for (int i = 0; i < CLIENTS; i++)
  {
    delete list[i];  //释放内存
  }
  cout << "完成.\n";

  system("pause");
  return 0;
}

4

a. 第一个任务是重新创建Port方法定义,因为前任被开除时销毁了方法定义。

看代码

b. 第二个任务是解释为什么有的方法重新定义了,而有些没有重新定义。

答:有的函数写在头文件作为内联函数,无需重新定义。

c. 第三个任务是解释为何没有将operator=()和operator<<()声明为虚的。

答:operator=()是不能继承的,因为不能将父类复制给子类。

operator<<()是友元函数,无法继承。

d. 第四个任务是提供VintagePort中各个方法的定义。
看代码。。。

#ifndef PORT_H_
#define PORT_H_
#include <iostream>

class Port
{
private:
  char *brand;
  char style[20];
  int bottles;
public:
  Port(const char *br = "none", const char *st = "none", int b = 0);
  Port(const Port &p);
  virtual ~Port() { delete[] brand; }
  Port &operator=(const Port &p);
  Port &operator+=(int b);
  Port &operator-=(int b);
  int BottleCount() const { return bottles; }
  virtual void Show() const;
  friend std::ostream &operator<<(std::ostream &os, const Port &p);
};

class VintagePort :public Port
{
private:
  char *nickname;
  int year;
public:
  VintagePort();
  VintagePort(const char *br, const char *st, int b, const char *nn, int y);
  VintagePort(const VintagePort &vp);
  ~VintagePort() { delete[] nickname; }
  VintagePort &operator=(const VintagePort &vp);
  void Show() const;
  friend std::ostream &operator<<(std::ostream &os, const VintagePort &vp);
};

#endif

 

#include <cstring>
#include "prot.h"

Port::Port(const char *br, const char *st, int b)
{
  brand = new char[strlen(br) + 1];
  strcpy_s(brand, strlen(br) + 1, br);
  strcpy_s(style, 20, st);
  bottles = b;
}

Port::Port(const Port &p)
{
  brand = new char[strlen(p.brand) + 1];
  strcpy_s(brand, strlen(p.brand) + 1, p.brand);
  strcpy_s(style, 20, p.style);
  bottles = p.bottles;
}

Port &Port::operator=(const Port &p)
{
  if (this == &p)
    return *this;
  delete[] brand;
  brand = new char[strlen(p.brand) + 1];
  strcpy_s(brand, strlen(p.brand) + 1, p.brand);
  strcpy_s(style, 20, p.style);
  bottles = p.bottles;
  return *this;
}

Port &Port::operator+=(int b)
{
  bottles += b;
  return *this;
}

Port &Port::operator-=(int b)
{
  bottles -= b;
  return *this;
}

void Port::Show() const
{
  using std::cout;
  using std::endl;
  cout << "Brand: " << brand << endl;
  cout << "Kind: " << style << endl;
  cout << "Bottles: " << bottles << endl;
}

std::ostream &operator<<(std::ostream &os, const Port &p)
{
  os << p.brand << ", " << p.style << ", " << p.bottles;
  return os;
}

VintagePort::VintagePort() :Port()
{
  nickname = new char[1];
  nickname[0] = '\0';
  year = 0;
}

VintagePort::VintagePort(const char *br, const char *st, int b, const char *nn, int y) :Port(br, st, b)
{
  nickname = new char[strlen(nn) + 1];
  strcpy_s(nickname, strlen(nn) + 1, nn);
  year = y;
}

VintagePort::VintagePort(const VintagePort &vp) :Port(vp)
{
  nickname = new char[strlen(vp.nickname) + 1];
  strcpy_s(nickname, strlen(vp.nickname) + 1, vp.nickname);
  year = vp.year;
}

VintagePort &VintagePort::operator=(const VintagePort &vp)
{
  if (this == &vp)
    return *this;
  Port::operator=(vp);
  delete[] nickname;
  nickname = new char[strlen(vp.nickname) + 1];
  strcpy_s(nickname, strlen(vp.nickname) + 1, vp.nickname);
  year = vp.year;
  return *this;
}

void VintagePort::Show() const
{
  Port::Show();
  std::cout << "NickName: " << nickname << std::endl;
  std::cout << "Year: " << year << std::endl;
}

std::ostream &operator<<(std::ostream &os, const VintagePort &vp)
{
  os << (const Port &)vp << ", ";
  os << vp.nickname << ", " << vp.year;
  return os;
}
#include <iostream>
#include "prot.h"

int main()
{
  Port p1("Gallo", "tawny", 20);
  VintagePort p2("Gallo", "tawny", 20, "The Noble", 1882);

  p1.Show();
  std::cout.put('\n');
  p2.Show();
  std::cout.put('\n');
  Port *p3;
  p3 = &p1;
  p3->Show();
  std::cout.put('\n');
  p3 = &p2;
  p3->Show();
  std::cout.put('\n');
  p1 += 10;
  p1.Show();
  std::cout.put('\n');
  p1 -= 10;
  p1.Show();
  std::cout.put('\n');
  VintagePort p4;
  p4 = p2;
  p4.Show();
  std::cout.put('\n');
  std::cout << p1 << std::endl;
  std::cout.put('\n');
  std::cout << p2 << std::endl;

  system("pause");
  return 0;
}

 

版权说明:
点赞

发表评论

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

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

微信扫一扫打赏