charpter15_homework.cpp
#include<iostream>
#include<stdexcept>
#include<string>
#include"tv_1.h"
#include"sales.h"
using namespace std;
void p15_1(void);
void p15_2(void);
void p15_3(void);
void p15_4(void);
int main()
{
//p15_1();
//p15_2();
//p15_3();
p15_4();
return 0;
}
//--------作业一------------
void p15_1(void)
{
Tv s42;
s42.settings();
s42.onoff();
s42.chanup();
s42.settings();
Remote grey;
grey.set_chan(s42,10);
grey.volup(s42);
grey.chanup(s42);
s42.settings();
Tv s58(Tv::On);
s58.set_mode();
grey.set_chan(s58,28);
s58.settings();
grey.show_function();
s58.set_func(grey);
grey.show_function();
grey.onoff(s58);
s58.set_func(grey);
}
////--------作业二-------------
////logic_error有string s
//class bad_hmean:public logic_error
//{
//public:
// bad_hmean(const string& s="hmean,a=-b"):logic_error(s){};
//};
//
//class bad_gmean:public logic_error
//{
//public:
// bad_gmean(const string& s="gmean,a<0||b<0"):logic_error(s){};
//};
//
//double hmean(double a,double b)
//{
// if(a==-b)
// throw bad_hmean();//跳转,找catch
// else
// return 2.0*a*b/(a+b);
//}
//double gmean(double a,double b)
//{
// if(a<0 || b<0)
// throw bad_gmean();//跳转,找catch
// else
// return sqrt(a*b);
//}
//void p15_2(void)
//{
// double x,y,z;
// cout<<"Enter two numbers: ";
// while(cin>>x>>y)
// {
// try
// {
// z=hmean(x,y);
// cout<<"hmean: "<<z<<endl;
// cout<<"gmean: "<<gmean(x,y)<<endl;
// cout<<"Enter again: ";
// }
// catch(bad_hmean& bh)
// {
// cout<<bh.what()<<endl;;
// cout<<"Enter again: ";
// continue;
// }
// catch(bad_gmean& bg)
// {
// cout<<bg.what()<<endl;
// cout<<"Bye!\n";
// break;
// }
// }
//
//}
//作业二三又相同类名称,分别编译
//-------作业三-------------
//logic_error有string s
//异常类基类,
class abc:public logic_error
{
private:
double a;
double b;
public:
//默认构造函数
abc(double x=0,double y=0,const string& s="abc"):logic_error(s),a(x),b(y){};
virtual void Show()const;
double aval()const{return a;};
double bval()const{return b;};
virtual~abc(){};//基类,析构为虚函数
};
inline void abc::Show()const
{
cout<<"abc: "<<a<<" , "<<b<<endl;
}
class bad_hmean:public abc
{
public:
bad_hmean(
double x=0,double y=0,const string& s="hmean,a=-b"):abc(x,y,s){};
void Show()const;
};
inline void bad_hmean::Show()const
{
cout<<"hmean: a=-b "<<abc::aval()<<" , "<<abc::bval()<<endl;
}
class bad_gmean:public abc
{
public:
bad_gmean(
double x=0,double y=0,const string& s="gmean,a<0||b<0"):abc(x,y,s){};
void Show()const;
};
inline void bad_gmean::Show()const
{
cout<<"gmean,a<0||b<0 "<<abc::aval()<<" , "<<abc::bval()<<endl;
}
double hmean(double a,double b)
{
if(a==-b)
throw bad_hmean(a,b);//跳转,找catch
else
return 2.0*a*b/(a+b);
}
double gmean(double a,double b)
{
if(a<0 || b<0)
throw bad_gmean(a,b);//跳转,找catch
else
return sqrt(a*b);
}
void p15_3(void)
{
double x,y,z;
cout<<"Enter two numbers: ";
while(cin>>x>>y)
{
try
{
z=hmean(x,y);
cout<<"hmean: "<<z<<endl;
cout<<"gmean: "<<gmean(x,y)<<endl;
cout<<"Enter again: ";
}
catch(abc& bh)
{
bh.Show();
cout<<"Enter again: ";
break;
}
}
}
//-----------作业四------------
void p15_4(void)
{
double vals1[12]={1000,2000,30000,40000,50000,60000,
7000,8000,9000,100000,11000,12000};
double vals2[12]={1,2,3,4,5,6,7,8,9,10,11,12};
Sales sales1(2011,vals1,12);
LabeledSales sales2("AAA",2012,vals2,12);
cout<<"----First try block----------:\n";
try
{
int i;
cout<<"Year= "<<sales1.Year()<<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(Sales::bad_index& bad)
{
cout<<bad.what()<<endl;
LabeledSales::nbad_index* nbad;
if(nbad=dynamic_cast<LabeledSales::nbad_index*>(&bad))
{
cout<<"Company: "<<nbad->label_val()<<endl;
cout<<"bad index: "<<nbad->bi_val()<<endl;
}
else
cout<<"bad index: "<<bad.bi_val()<<endl;
}
cout<<"----------Next 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()<<endl;
LabeledSales::nbad_index* nbad;
if(nbad=dynamic_cast<LabeledSales::nbad_index*>(&bad))
{
cout<<"Company: "<<nbad->label_val()<<endl;
cout<<"bad index: "<<nbad->bi_val()<<endl;
}
else
cout<<"bad index: "<<bad.bi_val()<<endl;
}
}
tv_1.h
#ifndef TV_1_H_
#define TV_1_H_
//两个类互为友元
class Tv
{
public:
//类友元
friend class Remote;
enum State{Off,On};//默认 Off为0,On为1
enum {MinVal,MaxVal};//音量
enum {Antenna,Cable};//模式
enum {TV,DVD};//输入
Tv(int s=Off,int mc=125):state(s),volume(0),maxchannel(mc),channel(2),mode(Cable),input(TV){};
bool volup();
bool voldown();
void onoff(){state=(state==On)?Off:On;};
bool ison()const{return state==On;};
void chanup();
void chandown();
void set_mode(){mode=(mode==Cable)?Antenna:Cable;};
void set_input(){input=(input==TV)?DVD:TV;};
void settings()const;
//非静态成员需要与特定对象相对应
/*void set_func(){Remote::function=(Remote::function==NORMAL)?NORMAL:ACT};*/
void set_func(Remote& r);
private:
int state;
int volume;
int maxchannel;
int channel;
int mode;
int input;
};
class Remote
{
public:
friend class Tv;
enum State{Off,On};//默认 Off为0,On为1
enum {MinVal,MaxVal};//音量
enum {Antenna,Cable};//模式
enum {TV,DVD};//输入
enum {NORMAL,ACT};//常规还是互动
private:
int mode;
int function;//新增成员变量
public:
Remote(int m=TV,int fun=NORMAL):mode(m),function(fun){};//构造函数
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_mode(Tv& t){t.set_mode();};
void set_input(Tv& t){t.set_input();};
void set_chan(Tv& t,int c){t.channel=c;};
void show_function()const;
};
#endif
tv_1.cpp
#include<iostream>
#include"tv_1.h"
using std::cout;
using std::endl;
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
{
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_func(Remote& r)
{
if(state==On)
r.function=(r.function==Remote::NORMAL)?Remote::ACT:Remote::NORMAL;
else
cout<<"Error\n";
}
void Remote::show_function()const
{
cout<<"function: "<<(function==NORMAL?"NORMAL":"ACT")<<endl;
};
sales.h
#ifndef SALES_H_
#define SALES_H_
#include<stdexcept>
#include<string>
using std::string;
class Sales
{
public:
enum{MONTHS=12};//公有符号常量,派生类也可以用
class bad_index:public std::logic_error
{
private:
int bi;//错误码
public:
bad_index(int ix,const std::string& s="Index error is Sales object!");
int bi_val()const{return bi;};//尽量使用const
virtual~bad_index()throw(){};//exception基类的throw()异常规范
};
explicit Sales(int yy=0);//关键字explicit防止单参数构造函数发生隐式转换
Sales(int yy,const double*gr,int n);//n是传入参数数组的数目
int Year()const{return year;};
virtual double operator[](int i)const;
virtual double& operator[](int i);//在函数中,放置throw跳转语句
virtual~Sales(){};
private:
double gross[MONTHS];
int year;
};
class LabeledSales:public Sales
{
public:
class nbad_index:public bad_index
{
private:
std::string lbl;
public:
nbad_index(const string& lb,int ix,
const string& s="Index error is LabeledSales object!");
const string& label_val()const{return lbl;};
~nbad_index()throw(){};
};
explicit LabeledSales(const string& lab="none",int yy=0);//默认参数,默认构造,记得关键字
LabeledSales(const string& lab,int yy,const double*gr,int n);
const string& Label()const{return label;};
double operator[](int i)const;
double& operator[](int i);//在函数中,放置throw跳转语句
~LabeledSales(){};//析构函数
private:
string label;
};
#endif
sales.cpp
#include<iostream>
#include<stdexcept>
#include<string>
#include"sales.h"
using std::string;
using std::cout;
using std::endl;
//错误类 bad_index
Sales::bad_index::bad_index(int ix,const string& s):bi(ix),logic_error(s)
{
}
//基类 Sales
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)//n是传入参数数组的数目
{
year=yy;
int lim=(n>MONTHS)?MONTHS:n;
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];
}
//错误类 nbad_index
LabeledSales::nbad_index::nbad_index(const string& lb,int ix,
const string& s):lbl(lb),bad_index(ix,s)
{
}
//派生类 LabeledSales
LabeledSales::LabeledSales(const string& lab,int yy):label(lab),Sales(yy)
{
}
LabeledSales::LabeledSales(const string& lab,
int yy,const double*gr,int n):label(lab),Sales(yy,gr,n)
{
}
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)//在函数中,放置throw跳转语句
{
if(i<0 || i>=MONTHS)
throw nbad_index(Label(),i);
return Sales::operator[](i);
}
如有错误,欢迎指正!