首页 > 编程 > C++ > 正文

c++ Primer Plus(第六版)第十⑤章习题,写代码之路

2019-11-10 17:41:05
字体:
来源:转载
供稿:网友

c++ PRimer Plus(习题15.1)

//对书上的友元类进行成员的增加// 一种简单的修改#include<iostream>#include"tv.h"int main(){	using std::cout;	Tv s42;	cout << "Initial settings for 42: /n";	s42.settings();	s42.onoOff();	cout << "/nAffter settinfs: /n ";	s42.settings();	Remote grey;	grey.chanup(s42);	grey.volup(s42);	s42.set_style(grey);	cout << "/nAffter setting: /n";	s42.settings();	grey.showstyle();	return 0;}
#pragma once#pragma execution_character_set("utf-8")//本文件为utf-8编码格式//书上的友元类的程序清单,顺便做15.1题目,增加一个成员#ifndef TV_H#define TV_Hclass 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(5),mode(Cable),input(TV){}	//默认构造函数	void onoOff() { state ^= 1; }				//切换模式,按位异或	bool ison()const { return state == On; }		//检查电视是否打开的方法	bool volup();								//调整音量的方法	bool voldown();	void chanup();								//调整频道的方法	void chandown();	void set_style(Remote &r);	//调整互动模式或者是常规模式的方法	void set_mode() { mode ^= 1; }	void set_input() { input ^= 1; }	void settings()const;private:	int state;	int volume;	int maxchannel;	int channel;	int mode;	int input;};class Remote{private:	int mode;	int style;public:	friend class Tv;				//让他们互相成为友元,Tv才能使用更改,Romote的style成员	enum { Normal, Action };	Remote(int m = Tv::TV):mode(m),style(Normal) {};	bool volup(Tv&t) { return t.volup(); };			//括号外面可以不加冒号	bool voldown(Tv&t) { return t.voldown(); };	void onoff(Tv&t) { t.onoOff(); }	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 showstyle()const;};#endif // !TV_H
//tv头文件的实现方法#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::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 << "Iuput = "			<< (input == TV ? "TV" : "DVD") << endl;	}}void Tv::set_style(Remote&r){	if (state == 1)		r.style ^= 1;	//接受的是一个遥控器对象,竟然无法更改私有成员}void Remote::showstyle()const{	std::cout << "Style = "		<< (style==Normal?"Normal":"Action")<< std::endl;}c++ Primer Plus(习题15.2)

//派生一个异常类以excception派生//并修改程序清单15.11,让what方法报告错误的函数名和问题性质#include<iostream>#include<exception>class bad_hmean :public std::exception				//Hanomic error class{private:	double v1;	double v2;public:	const char* what() 	{ return "bad argument to hmean(),invalid argument:a=-b/n"; }	bad_hmean(double a = 0, double b = 0) :v1(a), v2(b) {};};class bad_gmean :public std::exception				//Geometric error class{private:	double v1;	double v2;public:	const char* what() { return "bad argument to gmean(),argument shoule be >=0/n"; }	bad_gmean(double a = 0, double b = 0) :v1(a), v2(b) {};};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 << "Hanomic mean of " << x << " and " << y << " is " << z << endl;			cout << "Geometric mean of " << x << " and " << y << " is " << gmean(x, y) << endl;			cout << "Enter the next set of numbers<q to exit>";		}//使用try块		catch (bad_gmean&bg)					//捕捉异常输入		{			cout<<bg.what();			cout << "Try again./n";			continue;		}		catch (bad_hmean&hg)					//捕捉异常输入		{			cout<<hg.what();			cout << "Sorry,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);	}c++ Primer Plus(习题15.3)

//这题跟前面那题差不多,不过要从一个异常基类中派生出来//这样就具有多态性,根据错类型来调用方法//并修改程序清单15.11,让what方法报告错误的函数名和问题性质#include<iostream>class logic_error{protected:	double v1;	double v2;public:	logic_error(double a = 0, double b = 0) :v1(a), v2(b) {};	virtual void Report() {};		//虚函数,花括号必须的,不然vs2015链接错误};class bad_hmean:public logic_error			//Hanomic error class{public:	virtual void Report()	{		std::cout << "bad argument to hmean(),invalid argument:a=-b/n"			<< "You input " << logic_error::v1 << "=" << logic_error::v2 << std::endl;	}	bad_hmean(double a = 0, double b = 0) :logic_error(a,b) {};};class bad_gmean :public logic_error			//Geometric error class{public:	virtual void Report()	{ 		std::cout<<"bad argument to gmean(),argument shoule be >=0/n"			<< "You input " << logic_error::v1 << " or " << logic_error::v2 <<" <0"<< std::endl;	}	bad_gmean(double a = 0, double b = 0) :logic_error(a,b)  {};};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 << "Hanomic mean of " << x << " and " << y << " is " << z << endl;			cout << "Geometric mean of " << x << " and " << y << " is " << gmean(x, y) << endl;			cout << "Enter the next set of numbers<q to exit>";		}//使用try块		catch (logic_error&hg)					//捕捉异常输入		{			hg.Report();			cout << "Sorry,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);}c++ Primer Plus(习题15.4)
//这题修改书上的代码,这总比自己写容易点,不过还是要打代码//省不了的事,修改程序用一个catch来捕捉非法索引错误//而且要使用RTTI运行阶段类型识别的特性//说白了还是类的多态性,看需要调用哪个类的方法#include "sales.h"  #include <iostream>  int main(){	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);	std::cout << "First try block:/n";	try	{		int i;		std::cout << "Year = " << sales1.Year() << std::endl;		for (i = 0; i < 12; ++i)		{			std::cout << sales1[i] << ' ';			if (i % 6 == 5)				std::cout << std::endl;		}		std::cout << "Year = " << sales2.Year() << std::endl;		std::cout << "Label = " << sales2.Label() << std::endl;		for (i = 0; i <= 12; ++i)		{			std::cout << sales2[i] << ' ';			if (i % 6 == 5)				std::cout << std::endl;		}		std::cout << "End of try block 1./n";	}	catch (std::logic_error &le)		//祖先基类,引用派生类	{		std::cout << le.what();			//what方法接受一个string字符串		if (LabeledSales::nbad_index *ni = dynamic_cast<LabeledSales::nbad_index *>(&le))		{			//看能否安全转换,意思是多态性			std::cout << "Company: " << ni->label_val() << std::endl;			std::cout << "bad index: " << ni->bi_val() << std::endl;		}		else if (Sales::bad_index *bi = dynamic_cast<Sales::bad_index *>(&le))			std::cout << "bad index: " << bi->bi_val() << std::endl;	}	std::cout << "/nNext try block:/n";	try	{		sales2[2] = 37.5;		sales1[20] = 23345;		std::cout << "End of try block 2./n";	}	catch (std::logic_error &le)	{		//都是这样改,就这么简单		std::cout << le.what();		if (LabeledSales::nbad_index *ni = dynamic_cast<LabeledSales::nbad_index *>(&le))		{			std::cout << "Company: " << ni->label_val() << std::endl;			std::cout << "bad index: " << ni->bi_val() << std::endl;		}		else if (Sales::bad_index *bi = dynamic_cast<Sales::bad_index *>(&le))			std::cout << "bad index: " << bi->bi_val() << std::endl;	}	return 0;}


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选