C++ Primer Plus 第六版第十五章编程练习答案

//question1

//tv.h
#ifndef TV_H
#define TV_H

class Remote;
class Tv
{
    private:
        int state;
        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;
        void set_remote_mode(Remote & r);
};

class Remote
{
    private:
        int mode;
    public:
        friend class Tv;
        enum {Normal, Interact};
        Remote(int m = Normal) : mode(m) {}
        
        void showmode() const;
        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_input();}
};
#endif

 

//tv.cpp 
#include
#include "tv.h"

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

bool Tv::voldown()
{
    if (volume > MinVal)
    {
        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;
}

void Tv::settings() const
{
    using std::cout;
    using std::endl;
    cout << "TV is " << (state == Off ? "Off" : "On") << endl;
    if (state == On)
    {
        cout << "Volume setting = " << volume << endl;
        cout << "Channel setting = " << channel << endl;
        cout << "Mode = " << (mode == Antenna ? "Antenna" : "Cable") << endl;
        cout << "Input = " << (input == TV ? "TV" : "DVD") << endl;
    }
}

void Tv::set_remote_mode(Remote & r)
{
    if (state == On)
        r.mode = (r.mode == Remote::Normal) ? Remote::Interact : Remote::Normal;
}

void Remote::showmode() const
{
    using std::cout;
    using std::endl;
    cout << "Remote mode is : " << (mode == Normal ? "Normal" : "Interact") << endl;
}

 

//15_1.cpp
#include
#include "tv.h"

int main()
{
    using std::cout;
    using std::endl;
    Tv s42;
    Remote grey;
    cout << "Initial setting for 42\" TV:\n";
    s42.settings();
    
    cout << endl;
    grey.showmode();
    s42.set_remote_mode(grey);
    grey.showmode();
    cout << endl;
    
    s42.onoff();
    s42.chanup();
    cout << "\nAdjusted settings for 42\" TV:\n";
    s42.settings();
    
    grey.set_chan(s42, 10);
    grey.volup(s42);
    grey.volup(s42);
    cout << "\n42\" settings after using remote:\n";
    s42.settings();
    cout << endl;
    
    grey.showmode();
    s42.set_remote_mode(grey);
    grey.showmode();
    
    return 0;
}

//question2

#ifndef EXC_MEAN_H
#define EXC_MEAN_H
//exc_mean.h
#include
#include

class bad_hmean : public std::logic_error
{
    public:
        bad_hmean() : logic_error("bad arguments to hmean()") {}
};

class bad_gmean : public std::logic_error
{
    public:
        bad_gmean() : logic_error("bad arguments to gmean()") {}
};
#endif

//15_2.cpp
#include
#include
#include "exc_mean.h"

double hmean(double a, double b);
double gmean(double a, double b);
int main()
{
    using std::cout;
    using std::cin;
    using std::endl;
    
    double x, y, z;
    
    cout << "Enter two numbers: ";
    while (cin >> x >> y)
    {
        try{
            z = hmean(x, y);
            cout << "Harmonic mean of " << x << " and " << y << " is " << z << endl;
            cout << "Geometric mean of " << x << " and " << y << " is " << gmean(z, y) << endl;
            cout << "Enter next set of numbers : ";
        }
        catch (std::logic_error & le)
        {
            cout << le.what() << endl;
            cout << "Try again.\n";
            continue;
        }
    }
    cout << "Bye!\n";
    return 0;
}

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

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

//question3

//error.h
#ifndef ERROR_H
#define ERROR_H

#include
#include
#include

class error_mean : public std::logic_error
{
    private:
        double v1;
        double v2;
        std::string s;
    public:
        error_mean(double a = 0, double b = 0, std::string s = "error") : v1(a), v2(b), logic_error(s) {}
        virtual void report() = 0;
        virtual ~error_mean() throw() {}
};

class bad_hmean : public error_mean
{
    private:
        double v1;
        double v2;
    public:
        bad_hmean(double a = 0, double b = 0) : v1(a), v2(b), error_mean(a, b, "bad arguments to hmean()") {}
        void report();
};

class bad_gmean : public error_mean
{
    private:
        double v1;
        double v2;
    public:
        bad_gmean(double a = 0, double b = 0) : v1(a), v2(b), error_mean(a, b, "bad arguments to gmean()") {}
        void report();
};

void bad_hmean::report()
{
    std::cout << "bad_hmean() now!" << std::endl;
    std::cout << what() << "\n";
    std::cout << "The two numbers: " << v1 << ", " << v2 << "\n";
}

void bad_gmean::report()
{
    std::cout << "bad_gmean() now!" << std::endl;
    std::cout << what() << "\n";
    std::cout << "The two numbers: " << v1 << ", " << v2 << "\n";
}
#endif

//15_3.cpp
#include
#include
#include "error.h"

double hmean(double a, double b);
double gmean(double a, double b);
int main()
{
    using std::cout;
    using std::cin;
    using std::endl;
    
    double x, y, z;
    
    cout << "Enter two numbers: ";
    while (cin >> x >> y)
    {
        try{
            z = hmean(x, y);
            cout << "Harmonic mean of " << x << " and " << y << " is " << z << endl;
            cout << "Geometric mean of " << x << " and " << y << " is " << gmean(z, y) << endl;
            cout << "Enter next set of numbers : ";
        }
        catch (error_mean & em)
        {
            em.report();
            cout << "Try again.\n";
            continue;
        }
    }
    cout << "Bye!\n";
    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 std::sqrt(a * b);
}
 

//question4

//sales.h
#ifndef SALES_H
#define SALES_H
#include
#include
#include

class Sales
{
    public:
        enum {MONTHS = 12};
        class bad_index : public std::logic_error
        {
            private:
                int bi;
            protected:
                int bi_val() const {return bi;}
            public:
                explicit bad_index(int ix, const std::string & s = "Index error in Sales object\n");
                void report() const {std::cout << "bad index: " << bi_val() << std::endl;}
                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;
                const std::string & label_val() const {return lbl;}
            public:
                nbad_index(const std::string & lb, int ix, const std::string & s = "Index error in LabeledSales object\n");
                void report() const {std::cout << "Company: " << label_val() << std::endl;
                                     std::cout << "bad index: " << bad_index::bi_val() << std::endl;}
                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

//sales.cpp
#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; 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 std::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);
}

//15_4.cpp
#include
#include "sales.h"

int main()
{
    using std::cout;
    using std::endl;
    using std::cin;
    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 << "First try block:\n";
    try
    {
        int i;
        cout << "Year = " << sales1.Year() << endl;
        for (int i = 0; i < 12; i++)
        {
            cout << sales1[i] << ' ';
            if (i % 6 == 5)
                cout << endl;
        }
        cout << "Year = " << sales2.Year() << endl;
        cout << "Label = " << sales2.Label() << endl;
        for (i = 0; i <= 12; i++)
        {
            cout << sales2[i] << ' ';
            if (i % 6 == 5)
                cout << endl;
        }
        cout << "End of try block 1.\n";
    }
    catch(Sales::bad_index & bad)
    {
        cout << bad.what();
        bad.report();
    }
    cout << "\nNext try block:\n";
    try
    {
        sales2[2] = 37.5;
        sales1[20] = 23345;
        cout << "End of try block 2.\n";
    }
    catch(Sales::bad_index & bad)
    {
        cout << bad.what();
        bad.report();
    }
    cout << "Done.\n";
    return 0;
}

 

你可能感兴趣的:(C++)