//sales.h //15.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;
public:
explicit bad_index(int ix,const std::string & s = "Index error in Sales object\n");
int bi_val() const {return bi;}
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 = "Index error in LabeledSales object\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
//sales.cpp
#include "sales.h"
using std::string;
Sales::bad_index::bad_index(int ix, const std::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 std::string &lb, int ix, const std::string &s) : Sales::bad_index(ix, s)
{
lbl = lb;
}
LabeledSales::LabeledSales(const std::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);
}
//use_sales.cpp
#include <iostream>
#include "sales.h"
int main()
{
using std::cout;
using std::cin;
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 << "First try block:\n";
try
{
int i;
cout << "Year = " << sales1.Year() << std::endl;
for (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(std::logic_error & log)//能捕捉基类及其派生类的的异常
{
cout<<log.what();
if(LabeledSales::nbad_index* nbad = dynamic_cast<LabeledSales::nbad_index *>(&log))
{ //如果上面表示传入实参的类型为尖括号内的类型或其派生类,则返回传入对象的地址,否则传入空地址。
cout << "Company: " << nbad->label_val() << endl;
cout << "bad index: " << nbad->bi_val() << endl;
}
else if(LabeledSales::bad_index* bad = dynamic_cast<LabeledSales::bad_index *>(&log))
{
cout << "bad index: " << bad->bi_val() << endl;
}
cout << "\nNext try block:\n";
}
try
{
sales2[2] = 37.5;
sales1[20] = 23345;
cout << "End of try block 2.\n";
}
catch (std::logic_error &log)
{
cout << log.what();
if (LabeledSales::nbad_index *nbad = dynamic_cast<LabeledSales::nbad_index *>(&log))
{
cout << "Company: " << nbad->label_val() << endl;
cout << "bad index: " << nbad->bi_val() << endl;
}
else if (Sales::bad_index *bad = dynamic_cast<Sales::bad_index *>(&log))
cout << "bad index: " << bad->bi_val() << endl;
}
return 0;
}
//exc_mean.h //15.3
#include <iostream>
#include <stdexcept>
using namespace std;
class base : public logic_error
{
private:
double v1;
double v2;
public:
base(double a = 0,double b =0):v1(a),v2(b),logic_error("base"){}
virtual ~base(){}
virtual void mesg() const;
};
inline void base::mesg() const
{
std::cout<<"The argument 'a' is "<<v1<<" ,and the argument 'b' is "
<<v2<<endl;
}
class bad_hmean : public base
{
public:
bad_hmean(double a = 0,double b = 0) : base(a,b)
{
//logic_error("bad_hmean");
}
const char* what() const {return "bad_gmean";}
virtual void mesg() const;
};
inline void bad_hmean::mesg() const
{
base::mesg();
std::cout<<" the function name is "<<what()<<endl;
}
class bad_gmean : public base
{
public:
bad_gmean(double a = 0,double b = 0):base(a,b)
{
//logic_error("bad_gmean");
}
const char* what() const {return "bad_gmean";}//新定义了一个what方法,而不是重定义基类的what方法,因为不知道怎么使用才能满足条件。
virtual void mesg() const;
};
inline void bad_gmean::mesg() const
{
base::mesg();
std::cout<<" the function name is "<<(*this).what()<<endl;
}
//error4.cpp
#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::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(x,y)<<endl;
cout<<"Enter next set of numbers <q to quit>:";
}
catch(const base & bg)
{
bg.mesg();
cout<<"Done!\n";
break;
}
}
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);
}
//15.2
//exc_mean.h
#include <iostream>
#include <stdexcept>
#include <stdexcpt.h>
using namespace std;
class bad_hmean : public logic_error
{
private:
double v1;
double v2;
public:
bad_hmean(double a = 0,double b =0):v1(a),v2(b),logic_error("1"){}
void mesg();
void what();
};
inline void bad_hmean::what()
{
std::cout<<"hmean(" << v1<<" ,"<<v2<<"): "
<<"invalie arguments: a = -b\n";
}
class bad_gmean
{
public:
double v1;
double v2;
bad_gmean(double a = 0,double b = 0):v1(a),v2(b){}
const char* what();
};
inline const char* bad_gmean::what()
{
return "gmean() argument should be >= 0\n";
}
//error4.cpp
#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::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(x,y)<<endl;
cout<<"Enter next set of numbers <q to quit>:";
}
catch(bad_hmean & bg)
{
bg.what();
cout<<"Try again.\n";
continue;
}
catch(bad_gmean & hg)
{
hg.what();
cout<<"Values used: "<<hg.v1<<" , "<<hg.v2<<endl;
cout<<"Sorrt,you don't get to play any more.\n";
break;
}
}
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);
}
//tv.h -- Tv and Remote classes //15.1
#ifndef TV__H__
#define TV__H__
class Tv
{
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 change_sta_mode(Remote & r) const;
private:
int state;
int volume;
int maxchannel;
int channel;
int mode;
int input;
};
class Remote
{
private:
int sta_mode;
int mode;
public:
friend class Tv;
enum{NORMAl_STATUS,INTERACTIVE_STATUS};
Remote(int m = Tv::TV):mode(m),sta_mode(NORMAl_STATUS){}
bool volup(Tv & t) {return t.volup();}
bool voldown(Tv & t) {return t.voldown();}
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) {}
void show() const ;
};
#endif
//tv.cpp
#include <iostream>
#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::cin;
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::change_sta_mode(Remote & r) const
{
if(state == On)
r.sta_mode = (r.sta_mode == r.NORMAl_STATUS?r.INTERACTIVE_STATUS : r.NORMAl_STATUS);
}
void Remote::show() const
{
if(sta_mode == NORMAl_STATUS)
std::cout<<"the status mode is NORMAl_STATUS."<<std::endl;
else
std::cout<<"the status mode is INTERACTIVE_STATUS."<<std::endl;
}
//use_tv.cpp
#include <iostream>
#include "tv.h"
int main()
{
using std::cout;
Tv s42;
cout<<"Initial settings for 42\"TV :\n";
s42.settings();
s42.onoff();
s42.chanup();
cout<<"\nAdjusted settings for 42\"TV :\n";
s42.chanup();
cout<<"\nAdjusted settings for 42\"TV :\n";
s42.settings();
Remote grey;
grey.set_chan(s42,10);
grey.volup(s42);
grey.volup(s42);
cout<<"\n42\" settings after using remote:\n";
s42.settings();
Tv s58(Tv::On);
s58.set_mode();
grey.set_chan(s58,28);
cout<<"\n58\" settings:\n";
s58.settings();
grey.show();
s58.change_sta_mode(grey);
grey.show();
return 0;
}