C++ Premier Plus 6th edition - Programming excercise - Chapter11 - 5
阿新 • • 發佈:2018-11-28
這道題裡,用switch和while配合時,著實花了不少時間,還是使用不熟練所致。
排除非法輸入(非int)和非1、2、3的用法,儘量做到精簡。
實現1個需求的方法有無數種,程式碼也有無數種,但儘量用註釋記錄自己當時的思路,回頭看的時候可以找到不完善的地方進一步修改和調整。
stonewt.h
// stonewt.h -- definition for the Stonewt class
#ifndef STONEWT_H_
#define STONEWT_H_
class Stonewt
{
private:
enum {Lbs_per_stn = 14}; // pounds per stone
// Newly added:3 modes
enum Mode {STONE,INT_PDS,FLOAT_PDS};
Mode mode;// 3 modes
int stone; // whole stones
double pds_left; // fractional pounds
double pounds; // entire weight in pounds
// Newly added:
/*
relationship understanding,eg:
15.5 pounds == 1 stone 1.5 pds_left
*/
public:
Stonewt(double lbs); // constructor for double pounds
Stonewt(int stn, double lbs); // constructor for stone, lbs
Stonewt(); // default constructor
~Stonewt();
/*
Newly added: remove below 2 methods
void show_lbs() const; // show weight in pounds format
void show_stn() const; // show weight in stone format
*/
// reload operator + - *
Stonewt operator+(Stonewt&obj) const;
Stonewt operator-(Stonewt&obj) const;
Stonewt operator*(double n) const;
// set mode to STONE,POUNDS,PDS_LEFT
void setMode() ;
// friend:
// reload operator<<
friend std::ostream& operator<<(std::ostream&os,Stonewt& obj);
// reload operator*(double,objective),change position
friend Stonewt operator*(double n, const Stonewt& obj) ;
};
#endif
/*
data compeonents are same,state member is supposed to control show(),which appears
as reloaded operator<<.
*/
stonewt.cpp
// stonewt.cpp -- Stonewt methods
#include <iostream>
using std::cout;
using std::cin;
#include "stonewt.h"
#include<cstdlib>
// construct Stonewt object from double value
Stonewt::Stonewt(double lbs)
{
stone = int (lbs) / Lbs_per_stn; // integer division
pds_left = int (lbs) % Lbs_per_stn + lbs - int(lbs);
pounds = lbs;
// Newly added,set default form for <<
mode = STONE;
}
// construct Stonewt object from stone, double values
Stonewt::Stonewt(int stn, double lbs)
{
stone = stn;
pds_left = lbs;
pounds = stn * Lbs_per_stn +lbs;
// Newly added,set default form for <<
mode = STONE;
}
Stonewt::Stonewt() // default constructor, wt = 0
{
stone = pounds = pds_left = 0.0;
}
Stonewt::~Stonewt() // destructor
{
}
// Newly added: reload operator + - *
// the class Stonewt doesn't have methods to set
// values of data components automatically,so have to create new objective
Stonewt Stonewt::operator+(Stonewt&obj) const
{
double temp = pounds + obj.pounds;
return Stonewt(temp);
}
Stonewt Stonewt::operator-(Stonewt&obj) const
{
double temp = pounds - obj.pounds;
return Stonewt(temp);
}
Stonewt Stonewt::operator*(double n) const
{
double temp = pounds*n;
return Stonewt(temp);
}
/*
regarding mode, have easy way to realize
void stone_mode(){mode = STONE;}
void intPDS_mode(){mode = INT_PDS;}
void fltPDS_mode(){mode = FLOAT_PDS;}
but here just want to pratise the use of switch
*/
// have to set default mode before user choose
void Stonewt::setMode()
{
cout << "Which mode would you like?\n"
<< "(input: 1 for stone form, 2 for interger pounds form, 3 for floating-points form.\n";
int x;
// in case user's invalid input cause program stuck(eg, a,/,55ss,aa55,9)
// will still go into loop and get prompt
cin >> x;
while (cin.fail() || !(x == 1 || x == 2 || x == 3))
{
cout << "Invalid input, only number 1/2/3 is allowed. Pls enter again: ";
cin.clear();
while (cin.get() != '\n')//clear input queue
continue;
cin >> x;
}
switch (x)
{
case 1:
mode = STONE;
break;
case 2:
mode = INT_PDS;
break;
case 3:
mode = FLOAT_PDS;
break;
}
}
// Newly added: object is interpreted in stone form, integer pounds form,
// or floating - point pounds form.
// friend defination
std::ostream& operator<<(std::ostream&os, Stonewt& obj)
{
// can be (obj.mode == obj.STONE)?
if (obj.mode == Stonewt::STONE)
{
os << obj.stone << " stone, " << obj.pds_left << " pounds\n";
}
else if (obj.mode == Stonewt::INT_PDS)
{
os << (int)obj.pounds << " pounds\n";
}
else if (obj.mode == Stonewt::FLOAT_PDS)
{
os << obj.pounds << " pounds\n";
}
return os;
}
Stonewt operator*(double n, const Stonewt& obj)
{
// revolk member function operator*(double n)
return obj * n;
}
main.cpp
// main
#include<iostream>
#include"stonewt.h"
using std::cout;
int main()
{
// use 2 constructors
Stonewt s1(2000.3);
Stonewt s2(19, 14.5);
Stonewt s3(0);// empty objective
// use reloaded operator + - *
s3 = s1 + s2;
cout << "s1 + s2 result: " << s3 << std::endl;
s3 = s1 - s2;
cout << "s1 - s2 result: " << s3 << std::endl;
s3 = s1 * 5.5;
cout << "s1 * 5.5 result: " << s3 << std::endl;
// use friend oerator*
s3 = 5.5*s1;
// use setMode(),from INT_PDS
cout << "Now shows s3 result in another 2 forms.\n";
s3.setMode();
cout << "5.5*s1 result: " << s3 << std::endl;
// use setMode(),form FLOAT_PDS
s3.setMode();
cout << "5.5*s1 result: " << s3 << std::endl;
std::cin.get();
std::cin.get();
}