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;}
新闻热点
疑难解答
图片精选