C++ Primer第五版 第十五章编程练习(友元类、异常、RTTI)
1、//tv.h#ifndef TV_H_#define TV_H_#include<iostream>using std::cout;using std::endl;class Remote;class Tv{private:int state;int volume;int maxchannel;int channel;int ...
·
1、
//tv.h
#ifndef TV_H_
#define TV_H_
#include<iostream>
using std::cout;
using std::endl;
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, VCR};
enum{Normal, Interactive};
Tv(int s = Off, int mc = 100):state(s), volume(5), maxchannel(mc), channel(2), mode(Cable), input(TV){};
void on_off(){state = (state == On) ? Off : On;};
bool is_On()const{return (state == On);};
bool vol_up();
bool vol_down();
void chan_up();
void chan_down();
void set_mode(){mode = (mode == Antenna) ? Cable : Antenna;};
void set_input(){input = (input == TV) ? VCR : TV;};
void setting()const;
void set_rmode(Remote &r);
};
class Remote
{
private:
int mode;
int rmode;
public:
friend class Tv;
enum{Normal, Interactive};
Remote(int m = Tv::TV, int r = Normal):mode(m), rmode(r){};
void on_off(Tv &t){return t.on_off();};
bool vol_up(Tv &t){return t.vol_up();};
bool vol_down(Tv &t){return t.vol_down();};
void chan_up(Tv &t){return t.chan_up();};
void chan_down(Tv &t){return t.chan_down();};
void set_chan(Tv &t, int c){t.channel = c;};
void set_mode(Tv &t){return t.set_mode();};
void set_input(Tv &t){return t.set_input();};
void rmode_show();
};
#endif
//tv.cpp
#include<iostream>
#include"tv.h"
bool Tv::vol_up()
{
if(volume < Maxval)
{
volume++;
return true;
}
else
{
return false;
}
}
bool Tv::vol_down()
{
if(volume > Minval)
{
volume--;
return true;
}
else
{
return false;
}
}
void Tv::chan_up()
{
if(channel < maxchannel)
{
channel++;
}
else
{
channel = 1;
}
}
void Tv::chan_down()
{
if(channel > 1)
{
channel--;
}
else
{
channel = maxchannel;
}
}
void Tv::setting()const
{
using std::cout;
using std::endl;
cout << "TV is " << (state == On ? "On" : "Off") << 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" : "VCR") << endl;
}
}
void Tv::set_rmode(Remote &r)
{
if(is_On())
{
r.rmode = (r.rmode == Normal) ? Interactive : Normal;
r.rmode_show();
}
}
void Remote::rmode_show()
{
cout << "Present remote is " << (rmode == Normal ? "Normal" : "Interactive") << endl;
}
//main.cpp
#include<iostream>
#include"tv.h"
using namespace std;
int main()
{
Tv s27;
cout << "Initial setting for 27 \"TV :\n";
s27.setting();
s27.on_off();
s27.chan_up();
cout << "\nAdjusted settings for 27 \"TV :\n";
s27.setting();
Remote grey;
grey.set_chan(s27, 10);
grey.vol_up(s27);
grey.vol_up(s27);
cout << "\n27\"setting after using remote : \n";
s27.setting();
Tv s32(Tv::On);
s32.set_mode();
grey.set_chan(s32, 38);
//grey.rmode_show();
s32.set_rmode(grey);;
cout << "\n32\" setting for 32 \"TV \n";
s32.setting();
return 0;
}
2、
//mean.h
#ifndef MEAN_H_
#define MEAN_H_
#include<iostream>
#include<stdexcept>
#include<string>
using std::string;
using std::logic_error;
class bad_hmean:public logic_error
{
private:
string name;
public:
explicit bad_hmean(const string &nm = "hmean", const string &s = "Something Wrong in hmen() parameter. \n" ):name(nm), logic_error(s){};
string mesg(){return "hmean invalid arguments for a = -b ";};
virtual ~bad_hmean() throw(){};
};
class bad_gmean:public logic_error
{
private:
string name;
public:
explicit bad_gmean(const string &nm = "gmean", const string &s = "Something Wrong in gmean() parameter. \n"):name(nm), logic_error(s){};
string mesg(){return "gmean invaid arguments for a < 0 Or b < 0 ";};
virtual ~bad_gmean() throw(){};
};
#endif
//mean.cpp
#include<iostream>
#include<cmath>
#include<string>
#include"mean.h"
using namespace std;
double hmean(double a, double b);
double gmean(double a, double b);
int main()
{
double x, y, z;
cout << "Enter two number : ";
while(cin >> x >> y)
{
try
{
z = hmean(x, y);
cout << "Harmonic mean of " << "( " << x << " , " << y << " ) is " << z << endl;
cout << "Geomertic mean of " << "( " << x << " , " << y << " ) id " << gmean(x, y) << endl;
cout << "Enter next pair of number(Q or q to exit) : ";
}
catch(bad_hmean &bh)
{
cout << bh.what();
cout << bh.mesg() << endl;
cout << "Tray again : ";
continue;
}
catch(bad_gmean &bg)
{
cout << bg.what();
cout << bg.mesg() << endl;
cout << "Sorry, you can't get to try again . " << endl;
break;
}
}
cout << "done . " << endl;
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 sqrt(a * b);
}
3、
//mean.h
#ifndef MEAN_H_
#define MEAN_H_
#include<iostream>
#include<stdexcept>
#include<string>
using std::cout;
using std::endl;
using std::string;
using std::logic_error;
class bad_hmean:public logic_error
{
private:
double x;
double y;
string name;
public:
explicit bad_hmean(double a = 0, double b = 0, const string &nm = "hmean", const string &s = "Something Wrong in hmen() parameter. \n" ):x(a), y (b),name(nm), logic_error(s){};
void mesg(){ cout << name << " for " << "( " << x << " , " << y << " )" << "contains invalid arguments for a = -b " << endl;};
virtual ~bad_hmean() throw(){};
};
class bad_gmean:public logic_error
{
private:
double x;
double y;
string name;
public:
explicit bad_gmean(double a = 0, double b = 0, const string &nm = "gmean", const string &s = "Something Wrong in gmean() parameter. \n"):x(a), y(b), name(nm), logic_error(s){};
void mesg(){cout << name << " for " << "( " << x << " , " << y << " )" << " contains invaid arguments for a < 0 Or b < 0 " << endl;};
virtual ~bad_gmean() throw(){};
};
#endif
//main.cpp
#include<iostream>
#include<cmath>
#include<string>
#include"mean.h"
using namespace std;
double hmean(double a, double b);
double gmean(double a, double b);
int main()
{
double x, y, z;
cout << "Enter two number : ";
while(cin >> x >> y)
{
try
{
z = hmean(x, y);
cout << "Harmonic mean of " << "( " << x << " , " << y << " ) is " << z << endl;
cout << "Geomertic mean of " << "( " << x << " , " << y << " ) id " << gmean(x, y) << endl;
cout << "Enter next pair of number(Q or q to exit) : ";
}
catch(bad_hmean &bh)
{
cout << bh.what();
bh.mesg();
cout << "Tray again : ";
continue;
}
catch(bad_gmean &bg)
{
cout << bg.what();
bg.mesg();
cout << "Sorry, you can't get to try again . " << endl;
break;
}
}
cout << "done . " << endl;
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 sqrt(a * b);
}
4、
//sales.h
#ifndef SALES_H_
#define SALES_H_
#include<stdexcept>
#include<cstring>
class Sales
{
public:
enum{MONTH = 12};
private:
int year;
double gross[MONTH];
public:
class bad_index:public std::logic_error
{
private:
int bi;
public:
explicit bad_index(int ix, const char *s = "Index Error in Sales object . \n");
int bi_val()const{return bi;};
virtual ~bad_index() throw(){};
};
explicit Sales(int y = 0);
Sales(int y, const double *gr, int n);
virtual ~Sales(){};
int year_val()const{return year;};
virtual double operator[](int i)const throw(std::logic_error);
virtual double & operator[](int i) throw(std::logic_error);
};
class LabelSales:public Sales
{
public:
static const int STRLEN = 50;
private:
char label[STRLEN];
public:
class nbad_index:public Sales::bad_index
{
private:
char lbl[STRLEN];
public:
nbad_index(const char *lb, int ix, const char *s = "Index error in LabelSales object . \n");
const char *lbl_val(){return lbl;};
virtual ~nbad_index() throw(){};
};
explicit LabelSales(int y = 0, const char *s = "none");
LabelSales(int y, const double *gr, int n, const char *lb);
virtual ~LabelSales(){};
const char *label_val()const{return label;};
virtual double operator[](int i)const throw(std::logic_error);
virtual double & operator[](int i) throw(std::logic_error);
};
#endif
//sales.cpp
#include"sales.h"
Sales::bad_index::bad_index(int y, const char *s):bi(y), std::logic_error(s)
{
}
Sales::Sales(int y)
{
year = y;
for(int i = 0; i < MONTH; i++)
{
gross[i] = 0;
}
}
Sales::Sales(int y, const double *gr, int n)
{
year = y;
int lim = (n < MONTH) ? n : MONTH;
int i;
for(i = 0; i < lim; i++)
{
gross[i] = gr[i];
}
for(; i < MONTH; i++)
{
gross[i] = 0;
}
}
double Sales::operator[](int i)const throw(std::logic_error)
{
if(i < 0 || i >= MONTH)
{
throw bad_index(i);
}
return gross[i];
}
double & Sales::operator[](int i) throw(std::logic_error)
{
if(i < 0 || i >= MONTH)
{
throw bad_index(i);
}
return gross[i];
}
LabelSales::nbad_index::nbad_index(const char *lb, int ix, const char *s):Sales::bad_index(ix, s)
{
std::strcpy(lbl, lb);
}
LabelSales::LabelSales(int y, const char *s):Sales(y)
{
std::strcpy(label, s);
}
LabelSales::LabelSales(int y, const double *gr, int n, const char *s):Sales(y, gr, n)
{
std::strcpy(label, s);
}
double LabelSales::operator[](int i)const throw(std::logic_error)
{
if(i < 0 || i >= MONTH)
{
throw nbad_index(label_val(), i);
}
return Sales::operator[](i);
}
double & LabelSales::operator[](int i) throw(std::logic_error)
{
if(i < 0 || i >= MONTH)
{
throw nbad_index(label_val(), i);
}
return Sales::operator[](i);
}
//main.cpp
#include<iostream>
#include"sales.h"
using namespace std;
int main()
{
double s1[12] = {1978, 1989, 1996, 1967, 1994, 1993, 1986, 1999, 1978, 1984, 1983, 1992};
double s2[12] = {12, 13, 14, 11, 14, 16, 14, 18, 13, 12, 16, 17};
Sales sa1(2001, s1, 12);
LabelSales sa2(2004, s2, 12, "BlogStar");
Sales::bad_index *bs;
LabelSales::nbad_index *bl;
cout << "First try block : \n";
try
{
int i;
cout << "Year : " << sa1.year_val() << endl;
for(i = 0; i < 12; i++)
{
cout << sa1[i] << " ";
if(i % 6 == 5)
{
cout << endl;
}
}
cout << "Year : " << sa2.year_val() << endl;
cout << "Label : " << sa2.label_val() << endl;
for(i = 0; i < 12; i++)
{
cout << sa2[i] << " ";
if(i % 6 == 5)
{
cout << endl;
}
}
cout << "End of first block :\n";
}
catch(logic_error &bad)
{
cout << bad.what();
if(bs = dynamic_cast<Sales::bad_index *>(&bad))
{
cout << "Bad index : " << bs->bi_val() << endl;
}
else if(bl = dynamic_cast<LabelSales::nbad_index *>(&bad))
{
cout << "Company : " << bl->lbl_val() << endl;
cout << "Bad index : " << bl->bi_val() << endl;
}
else
{
cout << "Nono . " << endl;
}
}
cout << "Next try block : \n";
try
{
sa2[2] = 22.0;
sa2[20] = 32;
cout << "End of second block : \n";
}
catch(logic_error &bad)
{
cout << bad.what();
if(bs = dynamic_cast<Sales::bad_index *>(&bad))
{
cout << "Bad index : " << bs->bi_val() << endl;
}
else if(bl = dynamic_cast<LabelSales::nbad_index *>(&bad))
{
cout << "Company : " << bl->lbl_val() << endl;
cout << "Bad index : " << bl->bi_val() << endl;
}
else
{
cout << "Nono . " << endl;
}
}
cout << "done . " << endl;
return 0;
}
Practice makes perfect !
更多推荐
已为社区贡献2条内容
所有评论(0)