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 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 !

猜你喜欢

转载自blog.csdn.net/qq_37172182/article/details/85142779
今日推荐