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;}
新聞熱點
疑難解答
圖片精選