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;
}
发布了4 篇原创文章 · 获赞 0 · 访问量 69

猜你喜欢

转载自blog.csdn.net/qq_43600632/article/details/103025259
今日推荐