c++實現currency類(兩種)

c++實現一個currency類——簡要說明

練習來自[美]薩特吉·薩尼(Sartaj Sahni)寫的c++語言描述——數據結構、算法與應用中第一章c++回顧知識
其中區別開了兩個currency類,複製粘貼可得到舊currency類,對/**/進行刪除後可以使用新的currency類,並有附加函數操作
這是一個菜鳥的練習日記,所有的理解與學習都在代碼中註釋出來了,不知道這樣的備註方式對不對,如果你有更好的意見,歡迎提出

代碼

#include<iostream>
#include<string>
using namespace std;
enum signType{plus,minus};
//本打算用枚舉類型進行的
//但vs2017並不能識別plus和minus,故換成bool,其中+爲0,-爲1

class illegal_Parameter_Value
{//異常類,輸入不正確信息時用來拋出
public:
	illegal_Parameter_Value() :message("Illegal parameter value") {}
	//構造函數
	illegal_Parameter_Value(const char* theMessage) { message = theMessage; }
	//複製構造函數,如同調用構造函數的初始化的“”內容爲const char*類型,故聲明爲該形式,const不可少
	void outputMessage() { cout << message << endl; }
private:
	string message;
};
//報錯類

class currency
{//類聲明
public:
	currency(bool the_Sign = 0, unsigned long the_Dollars = 0, unsigned int the_Cents = 0);
	//構造函數,三輸入,若無變量進行構造就賦值爲0,0,0,該值爲缺省值
	//若初始值少於參數個數(有參數輸入),就按順序初始化,剩下的按照缺省值進行初始化
	~currency() {};
	//析構函數
	void setValue(bool, unsigned long, unsigned int);
	void setValue(double);

	bool getSign()const { return sign; }
	unsigned int getdollar()const { return dollars; }
	unsigned long getcent()const { return cents; }
	//const關鍵字指明 上方成員函數不會改變調用對象的值,故又稱常量函數
	currency add(const currency&)const;
	//此處的加法函數不會改變調用對象的值,而是作爲一個currency類型的值存在於環境中,也不會改變調用該函數的參數的值,故爲常量函數
	//add返回對象的值
	currency&increment(const currency&);
	//此處的加法函數會改變調用對象的值,故非常量函數,並且使用引用,可以減少函數在最後返回對象的結果時的複製的時間
	//increment返回對象的引用
	void output()const;

	//附加算法
	void input();//從標準流中讀取currency的值,然後賦給調用對象
	currency subtract(const currency&x)const;//從調用對象中減去參數對象x的值,返回結果(已實現)
	//未實現下列三個函數
	currency percent(const double&x)const;//返回一個currency類的對象,它的值是調用對象的x%。x爲double型
	currency multiply(const double&x)const;//返回一個currency類的對象,它的值是調用對象和x的乘積。x爲double型
	currency divide(const double&x)const;//返回一個currency類的對象,它的值是調用對象除以x的結果。x爲double型
private:
	bool sign;
	unsigned long dollars;
	unsigned int cents;
};
/*
class new_currency
{//新的類把小數點前後的值合起來用double存儲了
public:
	new_currency(bool the_sign = 0, unsigned long the_dollars = 0, unsigned int the_cents = 0);
	~new_currency() {}
	void set_value(bool, unsigned long, unsigned int);
	void set_value(double);

	bool getsign()const { if (amount < 0)return 1; else return 0; }
	unsigned long get_dollars()const { if (amount < 0)return (-amount) / 100; else return amount / 100; }
	unsigned int get_cents()const { if (amount < 0)return (-amount) - get_dollars(); else return amount - get_dollars(); }

	new_currency add(const new_currency&x)const;
	new_currency &increment(const new_currency&x) { amount += x.amount; return *this; }

	new_currency operator +(const new_currency&)const;
	new_currency& operator+=(const new_currency&x) { amount += x.amount; return *this; }

	void output(ostream&out)const;//調用全局範圍的函數ostream&operator<<(ostream&out,const new_currency&)即可使用<<
	friend ostream&operator<<(ostream&output,const new_currency&x);
private:
	double amount;
};
//一個新的currency類,把dollar和cent用amount一個數存儲,並且amount爲整數
*/

currency::currency(bool the_Sign, unsigned long the_Dollars, unsigned int the_Cents)
{
	setValue(the_Sign, the_Dollars, the_Cents);
}
//調用成員函數初始化
void currency::setValue(bool the_Sign, unsigned long the_Dollars, unsigned int the_Cents)
{//給調用對象的數據成員賦值
	if (the_Cents > 99)throw illegal_Parameter_Value("cents should be<100");//當輸入過大時拋出非法信息
	sign = the_Sign;
	dollars = the_Dollars;
	cents = the_Cents;
}
void currency::setValue(double the_Amount)
//double和float可帶符號
{
	if (the_Amount < 0)//判斷輸入數的正負,並提取前邊符號
	{
		sign = 1;
		the_Amount = -the_Amount;
	}
	else sign = 0;
	dollars = (unsigned long)the_Amount;//強制轉換爲無符號,去除符號問題,其中unsigned long加不加int都一樣
	cents = (unsigned int)((the_Amount + 0.001 - dollars) * 100);//0.01彌補計算機存儲數據總會偏小的誤差,強制轉換數據類型
}//long佔四字節,int在16位系統中佔2字節,在32位系統中佔4字節,故一般情況是一樣的,包括unsigned int和unsigned long
currency currency::add(const currency& x)const
{
	double a1, a2, a3;
	currency result;//返回一個新聲明的變量就不會改變輸入參量的值了
	a1 = dollars * 100 + cents;
	if (sign == 1)a1 = -a1;//此時a1爲帶符號的double型
	a2 = x.dollars * 100 + x.cents;
	if (x.sign == 1) a2 = -a2;
	a3 = a1 + a2;//a3符號由運算得來
	if (a3 < 0)//分離a3的符號和數值
	{
		result.sign = 1;//給result變量符號賦值
		a3 = -a3;//a3爲數值,不帶符號
	}
	else result.sign = 0;
	result.dollars = a3 / 100;
	result.cents = a3 - result.dollars * 100;
	return result;//返回result不改變調用的參數值
}
currency& currency::increment(const currency& x)
{//把參數對象的貨幣值加到調用對象上,這個函數改變了調用對象的值,不改變引用的x的值,並且x前有const聲明
	*this = add(x);
	return *this;//返回到x中,改變參數值
}
void currency::output()const
{
	if (sign == 1)cout << "-";
	cout << "$" << dollars << ".";
	if (cents < 10)cout << "0";
	cout << cents << endl;
}
currency currency::subtract(const currency&x)const
{//課後題
	currency result;
	double y1, y2;
	if (sign == 1)
	{
		y1 = -(dollars * 100 + cents);
		//cout << "y1一開始爲負,此時應當爲正:" << y1 << endl;
	}
	y1 = dollars * 100 + cents;
	//cout << "對y1操作之後y1應爲一正數:" << y1 << endl;
	if (x.sign == 1)
		y2 = -(dollars * 100 + cents);
	y2 = x.dollars * 100 + x.cents;
	//cout << "對y2操作之後y2應爲一正數:" << y2 << endl;
	double y3 = y1 - y2;
	//cout << "y1-y2=" << y3 << endl;
	if (y3 < 0)
	{
		y3 = -y3;
		result.sign = 1;
	}
	else
		result.sign = 0;
	result.dollars = y3 / 100;
	//cout << "result.dollars=";
	//cout << result.dollars << endl;
	result.cents = y3 - result.dollars * 100;
	//cout << "result.cents=" << result.cents << endl;
	return result;
}
/*
new_currency::new_currency(bool the_sign, unsigned long the_dollars, unsigned int the_cents)
{
	set_value(the_sign, the_dollars, the_cents);
}
void new_currency::set_value(bool the_sign, unsigned long the_dollars, unsigned int the_cents)
{
	if (the_cents > 99)
		throw illegal_Parameter_Value("too much cents,the cents should below 100");
	if (the_sign == 1)
	{
		double the_numbers = the_dollars * 100 + the_cents;
		amount = -the_numbers;
	}
	else
		amount = the_dollars * 100 + the_cents;
}
void new_currency::set_value(double Amount)
{
	if (Amount < 0)
		amount = (Amount - 0.001) * 100;
	else
		amount = (Amount + 0.001) * 100;
}
new_currency new_currency::add(const new_currency&x)const
{
	new_currency y;
	y.amount = x.amount + amount;
	return y;
}
//********************************************************************************************
//********************************************************************************************
void new_currency::output(ostream &out)const
{//若沒有下方輸出流的定義,此處的輸出流會出error
	double Amount;
	//將平時使用的cout換爲輸入參數即可
	if (amount < 0)
	{
		out << "-";
		Amount = -amount;
	}
	else
		Amount = amount;
	unsigned long dollars = Amount / 100;
	out << "$" << dollars << ".";
	unsigned int cents = Amount - dollars * 100;
	if (cents < 10)
		out << "00";
	out << cents;
}

ostream&operator<<(ostream&out, const new_currency&x)
{//格式即ostream&operator<<(ostream&,自定義類&)
	//譚浩強c++教程中p314談及輸入輸出流不能定義爲成員函數,只能定義爲友元函數,此處即非成員函數
	x.output(out);
	//需要先定義一個類的輸出函數,並使輸出函數有參數,並且還要是ostream的引用作爲參數輸入
	return out;
	//返回一個對象的引用後續可以對同一個對象進行其他操作,返回對象只是返回一個拷貝副本,無法進行後續操作
	//如cout<<a<<b<<endl;
	//此處cout的<<函數返回的就是引用,連續使用輸出流即引用符號的效果
}
//此處爲全局範圍的函數
//********************************************************************************************
//********************************************************************************************
new_currency new_currency::operator+(const new_currency&x)const
{
	new_currency y;
	y.amount = amount + x.amount;
	return y;
}
ostream&operator<<(ostream&output,const new_currency&x)
{
	double the_amount;
	if (x.amount < 0)
	{
		output << "-";
		the_amount = -x.amount;
	}
	else
		the_amount = x.amount;
	unsigned long dollar = the_amount / 100;
	unsigned int cent = the_amount - dollar * 100;
	output << "$" << dollar << ".";
	if (cent < 10)
		output << "0";
	output << cent;
	return output;
}
*/
int main()
{
	currency g, h(0, 3, 50), i, j;
	g.setValue(1, 2, 25);
	cout << "g的值爲:" << endl;
	g.output();
	cout << "g.add(h)的值爲:" << endl;
	g.add(h).output();
	cout << "g.abstract(h)的值爲:" << endl;
	g.subtract(h).output();
	cout << "h的值爲:" << endl;
	h.output();
	cout << "g.increment(h)的值爲:" << endl;
	g.increment(h).output();
	cout << "h的值爲:" << endl;
	h.output();
	cout << "g的值爲:" << endl;
	g.output();
	cout << "h的值爲:" << endl;
	h.output();
	i.setValue(-6.45);
	j = h.add(g);
	h.output();
	cout << "+";
	g.output();
	cout << "=";
	j.output();
	cout << endl;
	j = i.add(g).add(h);
	j = i.increment(g).add(h);
	cout << "Attempting to initialize with cents = 152" << endl;
	try { i.setValue(0, 3, 152); }
	catch (illegal_Parameter_Value e)
	{
		cout << "Caught thrown exception" << endl;
		e.outputMessage();
	}
	/*
	new_currency a, b(0, 3, 50), c, d;
	a.set_value(1, 2, 25);
	c.set_value(-6.25);
	cout << "a= " << a << endl;
	cout << "b= " << b << endl;
	cout << "c= " << c << endl;
	cout << "d= " << d << endl;
	d = b + a;
	cout <<"  d=b+a:  "<< b << "+" << a << "=" << d << endl<<endl;
	d = a + b + c;
	cout <<"d=a+b+c: "<< a << "+" << b << "+" << c << "=" << d << endl;
	cout << "increment of new_currency: " << c << "by: " << a << endl << "and then add:" << b << endl;
	d = (c += a) + b;
	cout << "the result is : " << d << endl;
	cout << "incremented object is: " << c << endl;
	//error testing
	cout << "attempting to initialize with cents=152" << endl;
	try { c.set_value(0, 3, 152); }
	catch (illegal_Parameter_Value e)
	{
		cout << "caught thrown exception" << endl;
		e.outputMessage();
	}*/
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章