神秘博客

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

1

随便用了示例的程序测试,懒得写互动程序

#ifndef TV_H_
#define TV_H_

class Remote;

class Tv
{
private:
  int state; //TV状态
  int volume;  //音量
  int maxchannel;  //最大频道
  int channel; //频道
  int mode; //网络模式
  int input;  //输入
public:
  friend class Remote;
  enum { Off, On };
  enum { MinVal, MaxVal = 20 };
  enum { Antenna, Cable };
  enum { TV, DVD };
  Tv(int s = Off, int mc = 125) :state(s), volume(5), maxchannel(mc), channel(2), mode(Cable), input(TV) {}
  void onoff() { state = (state == On) ? Off : On; }
  bool ison() const { return state == On; }
  bool volup();
  bool voldown();
  void chanup();
  void chandown();
  void set_mode() { mode = (mode == Antenna) ? Cable : Antenna; }
  void set_input() { input = (input == TV) ? DVD : TV; }
  void settings() const;
  bool set_Rmode(Remote &t);
};

class Remote
{
private:
  int mode;
  int Rmode;
public:
  friend class Tv;
  Remote(int m = Tv::TV, int Rm = Tv::On) :mode(m), Rmode(Rm) {}
  bool volup(Tv &t) { return t.volup(); }
  bool voldown(Tv &t) { return t.voldown(); }
  void onoff(Tv &t) { t.onoff(); }
  void chanup(Tv &t) { t.chanup(); }
  void chandown(Tv &t) { t.chandown(); }
  void set_chan(Tv &t, int c) { t.channel = c; }
  void set_mode(Tv &t) { t.set_mode(); }
  void set_input(Tv &t) { t.set_mode(); }
  void ShowRmode() const;
};


#endif

#include <iostream>
#include "tv.h"

bool Tv::volup()
{
  if (volume < MaxVal)
  {
    volume++;
    return true;
  }
  else
    return false;
}

bool Tv::voldown()
{
  if (volume > MaxVal)
  {
    volume--;
    return true;
  }
  else
    return false;
}

void Tv::chanup()
{
  if (channel < maxchannel)
    channel++;
  else
    channel = 1;
}

void Tv::chandown()
{
  if (channel > 1)
    channel--;
  else
    channel = maxchannel;
}

bool Tv::set_Rmode(Remote &t)
{
  if (state == On)
  {
    t.Rmode = (t.Rmode == On) ? Off : On;
    return true;
  }
  return false;
}

void Tv::settings() const
{
  using std::cout;
  using std::endl;
  cout << "TV 状态: " << (state == Off ? "关闭" : "开启") << endl;
  if (state == On)
  {
    cout << "音量设定 = " << volume << endl;
    cout << "频道设定 = " << channel << endl;
    cout << "模式 = " << (mode == Antenna ? "无线" : "有线") << endl;
    cout << "输入 = " << (input == TV ? "TV" : "DVD") << endl;
  }
}

void Remote::ShowRmode() const
{
  std::cout << "遥控器状态: " << (Rmode == Tv::On ? "常规模式" : "互动模式") << std::endl;
}
#include <iostream>
#include "tv.h"

int main()
{
  using std::cout;

  Tv s42;

  cout << "42\" TV 初始设置:\n";
  s42.settings();
  s42.onoff();	
  s42.chanup();
  cout << "\n42\" TV 调整设置:\n";
  s42.settings();

  Remote grey;

  grey.set_chan(s42, 10);
  grey.volup(s42);
  grey.volup(s42);
  cout << "\n42\" TV 使用遥控设置:\n";
  s42.settings();
  grey.ShowRmode();

  Tv s58(Tv::On);
  s58.set_mode();
  grey.set_chan(s58, 28);
  s58.set_Rmode(grey);
  cout << "\n58\" TV 设置:\n";
  s58.settings();
  grey.ShowRmode();

  system("pause");
  return 0;
}

2

#include <iostream>
#include <stdexcept>

class bad_hmean :public std::logic_error
{
public:
  bad_hmean(const char *s = "bad_hmean 异常\n") :std::logic_error(s) {}
};


class bad_gmean :public std::logic_error
{
public:
  bad_gmean(const char *s = "bad_gmean 异常\n") :std::logic_error(s) {}
};
#include <iostream>
#include <cmath>
#include "exc_mean.h"

double hmean(double a, double b);
double gmean(double a, double b);

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

  double x, y, z;

  cout << "请输入两个数字: ";
  while (cin >> x >> y)
  {
    try
    {
      z = hmean(x, y);
      cout << x << " 和 " << y << " 的调和平均数为 " << z << endl;
      cout << x << " 和 " << y << " 的几何平均值为 " << gmean(x, y) << endl;
      cout << "请输入下一组数字[q退出]: ";
    }
    catch (bad_hmean &bg)
    {
      cout << bg.what();
      cout << "再试一次.\n";
      continue;
    }
    catch (bad_gmean &hg)
    {
      cout << hg.what();
      cout << "对不起, 你不能再玩了.\n";
      break;
    }
  }
  cout << "完成.\n";

  system("pause");
  return 0;
}

double hmean(double a, double b)
{
  if (a == -b)
    throw bad_hmean("bad_hmean 异常\n无效参数:  a = -b\n");
  return 2.0*a*b / (a + b);
}

double gmean(double a, double b)
{
  if (a < 0 || b < 0)
    throw bad_gmean("bad_gmean 异常\n参数应 >= 0\n");
  return sqrt(a*b);
}

3

#include <iostream>
#include <stdexcept>

class bad_err :public std::logic_error
{
public:
  double v1;
  double v2;
  bad_err(double a, double b, const char *s = "未知异常\n") :v1(a), v2(b), std::logic_error(s) {}
  virtual void mesg() const = 0;
  virtual ~bad_err() {}
};

class bad_hmean :public bad_err
{
public:
  bad_hmean(double a, double b, const char *s = "bad_hmean 异常\n") :bad_err(a, b, s) {}
  void mesg() const
  {
    std::cout << bad_err::what();
    std::cout << "无效参数: " << bad_err::v1 << " = " << bad_err::v2 << std::endl;
  }
};


class bad_gmean :public bad_err
{
public:
  bad_gmean(double a, double b, const char *s = "bad_gmean 异常\n") :bad_err(a, b, s) {}
  void mesg() const
  {
    std::cout << bad_err::what();
    std::cout << "参数 " << bad_err::v1 << " and " << bad_err::v2 << " 应该为 >= 0" << std::endl;
  }
};
#include <iostream>
#include <cmath>
#include "exc_mean.h"

double hmean(double a, double b);
double gmean(double a, double b);

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

  double x, y, z;

  cout << "请输入两个数字: ";
  while (cin >> x >> y)
  {
    try
    {
      z = hmean(x, y);
      cout << x << " 和 " << y << " 的调和平均数为 " << z << endl;
      cout << x << " 和 " << y << " 的几何平均值为 " << gmean(x, y) << endl;
      cout << "请输入下一组数字[q退出]: ";
    }
    catch (bad_err &hg)
    {
      hg.mesg();
      cout << "对不起, 你不能再玩了.\n";
      break;
    }
  }
  cout << "完成.\n";

  system("pause");
  return 0;
}

double hmean(double a, double b)
{
  if (a == -b)
    throw bad_hmean(a, b);
  return 2.0*a*b / (a + b);
}

double gmean(double a, double b)
{
  if (a < 0 || b < 0)
    throw bad_gmean(a, b);
  return sqrt(a*b);
}

4

#ifndef SALES_H_
#define SALES_H_

#include <stdexcept>
#include <string>

class Sales
{
  public:
    enum
    {
        MONTHS = 12
    };
    class bad_index : public std::logic_error
    {
      private:
        int bi;
    std::string temp; //无用数据,用来临时虚函数label_val返回,因为没有增加一个新基类,label_val无法纯虚,不然bad_index类无法创建
      public:
        explicit bad_index(int ix, const std::string &s = "Sales 对象中的索引错误\n");
        int bi_val() const { return bi; }
    virtual const std::string &label_val() const { return temp; }
        virtual ~bad_index() throw() {}
    };
    explicit Sales(int yy = 0);
    Sales(int yy, const double *gr, int n);
    virtual ~Sales() {}
    int Year() const { return year; }
    virtual double operator[](int i) const;
    virtual double &operator[](int i);

  private:
    double gross[MONTHS];
    int year;  //年代
};

class LabeledSales : public Sales
{
  public:
    class nbad_index : public Sales::bad_index
    {
      private:
        std::string lbl;  //公司

      public:
        nbad_index(const std::string &lb, int ix, const std::string &s = "LabeledSales 对象中的索引错误\n");
        const std::string &label_val() const { return lbl; }
        virtual ~nbad_index() throw() {}
    };
    explicit LabeledSales(const std::string &lb = "none", int yy = 0);
    LabeledSales(const std::string &lb, int yy, const double *gr, int n);
    virtual ~LabeledSales() {}
    const std::string &Label() const { return label; }
    virtual double operator[](int i) const;
    virtual double &operator[](int i);
  private:
    std::string label;
};

#endif
#include "sales.h"
using std::string;

Sales::bad_index::bad_index(int ix, const string &s) : std::logic_error(s), bi(ix)
{
}

Sales::Sales(int yy)
{
    year = yy;
    for (int i = 0; i < MONTHS;i++)
        gross[i] = 0;
}

Sales::Sales(int yy, const double *gr, int n)
{
    year = yy;
    int lim = (n < MONTHS) ? n : MONTHS;
    int i;
    for (i = 0; i < lim;i++)
        gross[i] = gr[i];
    for (; i < MONTHS;i++)
        gross[i] = 0;
}

double Sales::operator[](int i) const
{
    if (i < 0 || i >= MONTHS)
        throw bad_index(i);
    return gross[i];
}

double &Sales::operator[](int i)
{
    if (i < 0 || i >= MONTHS)
        throw bad_index(i);
    return gross[i];
}

LabeledSales::nbad_index::nbad_index(const string &lb, int ix, const string &s) : Sales::bad_index(ix, s)
{
    lbl = lb;
}

LabeledSales::LabeledSales(const string &lb, int yy) :Sales(yy)
{
    label = lb;
}

LabeledSales::LabeledSales(const string &lb, int yy, const double *gr, int n) : Sales(yy, gr, n)
{
    label = lb;
}

double LabeledSales::operator[](int i) const
{
    if (i < 0 || i >= MONTHS)
        throw nbad_index(Label(), i);
    return Sales::operator[](i);
}

double &LabeledSales::operator[](int i)
{
    if (i < 0 || i >= MONTHS)
        throw nbad_index(Label(), i);
    return Sales::operator[](i);
}
#include <iostream>
#include "sales.h"

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

    double vals1[12] =
        {
            1220, 1100, 1122, 2212, 1232, 2334,
            2884, 2393, 3302, 2922, 3002, 3544};

    double vals2[12] =
        {
            12, 11, 22, 21, 32, 34,
            28, 29, 33, 29, 32, 35};

    Sales sales1(2011, vals1, 12);
    LabeledSales sales2("Blogstar", 2012, vals2, 12);

    cout << "第一个 try 块:\n";
    try
    {
        int i;
        cout << "年代 = " << sales1.Year() << endl;
        for (i = 0; i < 12; ++i)
        {

            cout << sales1[i] << ' ';
            if (i % 6 == 5)
                cout << endl;
        }
        cout << "年代 = " << sales2.Year() << endl;
        cout << "公司 = " << sales2.Label() << endl;
        for (i = 0; i <= 12; ++i)
        {

            cout << sales2[i] << ' ';
            if (i % 6 == 5)
                cout << endl;
        }
        cout << "try 块 1 结束.\n";
    }
    catch (LabeledSales::bad_index &bad)
    {
        cout << bad.what();
    LabeledSales::nbad_index *temp = nullptr;
    if (temp = dynamic_cast<LabeledSales::nbad_index *>(&bad))
      cout << "公司: " << bad.label_val() << endl;
        cout << "错误下标: " << bad.bi_val() << endl;
    }

    cout << "\n下个 try 块:\n";
    try
    {
        sales2[2] = 37.5;
        sales1[20] = 23345;
        cout << "try 块 2 结束.\n";
    }
    catch (LabeledSales::bad_index &bad)
    {
        cout << bad.what();
    LabeledSales::nbad_index *temp = nullptr;
    if (temp = dynamic_cast<LabeledSales::nbad_index *>(&bad))
      cout << "公司: " << bad.label_val() << endl;
        cout << "错误下标: " << bad.bi_val() << endl;
    }

    cout << "完成\n";

  system("pause");
    return 0;
}

 

版权说明:
点赞

发表评论

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

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

微信扫一扫打赏