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

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_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(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;
}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值