操作符重载
在上总结(一)中,C u r r e n c y类包含了几个与C + +标准操作符相类似的成员函数,例如, A d d进行+操作,I n c r e m e n t进行+ =操作。直接使用这些标准的C + +操作符比另外定义新的函数(如A d d,I n c r e m e n t)要自然得多。可以借助于操作符重载( operator overloading)的过程来使用+和+ =。操作符重载允许扩充现有C + +操作符的功能,以便把它们直接应用到新的数据类型或类。
在C u r r e n c y类中重载了流插入操作符,但没有定义相应的成员函数,而重载+和+ =时则把它们定义为类成员。同样,也可以重载流抽取操作符> >而不需要把它定义为类成员。
由于C u r r e n c y对象的p r i v a t e成员对于非类成员函数来说不可访问(被重载的< <不是类成员,而+是),所以,重载< <的代码不能引用对象x的私有成员
(在< <操作中x将被插入到输出流中)。
使用操作符重载的类定义:
class Currency {
p u b l i c :
// 构造函数
Currency(sign s = plus, unsigned long d = 0, unsigned int c = 0);
// 析构函数
~Currency() {}
bool Set(sign s, unsigned long d, unsigned int c);
bool Set(float a);
sign Sign() const
{if (amount < 0) return minus;
else return plus;}
unsigned long Dollars() const
{if (amount < 0) return (-amount) / 100;
else return amount / 100;}
unsigned int Cents() const
{if (amount < 0)
return -amount - Dollars() * 100;
else return amount - Dollars() * 100;}
Currency operator+(const Currency& x) const;
Currency& operator+=(const Currency& x)
{amount += x.amount; return *this;}
void Output(ostream& out) const;
p r i v a t e :
long amount;
} ;
+,O u t p u t和< <的代码
Currency Currency::operator+(const Currency& x) const
{// 把x 累加至* t h i s .Currency y;y.amount = amount + x.amount;return y;}
void Currency::Output(ostream& out) const{// 将currency 的值插入到输出流long a = amount;if (a < 0) {out << '-' ; a = -a ; }
long d = a / 100; // 美元out << '<< d << '.' ;
int c = a - d * 100; // 美分 if (c < 10) out << "0"; out << c; } // 重载< <
ostream& operator<<(ostream& out, const Currency& x)
{x.Output(out); return out;}
引发异常
构造函数和set函数这样的类成员在执行预定的任务时有可能会失败。在构造函数中处理错误条件的方法是退出程序,而在S e t中则返回一个失败信号( f a l s e)给调用者。
为了引发
异常,必须首先定义一个异常类,比如BadInitialization .
// 初始化失败 class BadInitializers { p u b l i c : BadInitializers() {} } ;
调用方式如下:
void Currency::Set(sign s, unsigned long d, unsigned int c) {// 取值 if (c > 99) throw BadInitializers(); amount = d * 100 + c; if (s == minus) amount = -amount; }
友元和保护类成员
一个类的private成员仅对于类的成员函数是可见的。在有些应用中,必须把对这些private成员的访问权授予其他的类和函数,做法是把这些类和函数定义为友元(friend)。
在Currency类中定义了一个成员函数O u t p u t以便于对操作符<<的重载。定义这个函数是必要的,因为如下函数:
ostream& operator <<(ostream& out, const Currency& x)
不能访问p r i v a t e成员a m o u n t。我们可以把ostream& operator<<描述为C u r r e n c y类的友元,从而避免定义附加的函数,这样就把Currency所有成员(包括p r i v a t e成员及p u b l i c成员)的访问权都授予了该函数。
为了产生友元,需要在C u r r e n c y类描述中引入friend 语句。如下所示:
class Currency { friend ostream& operator<< (ostream&, const Currency&); p u b l i c : // 重载< < ostream& operator<<(ostream& out, const Currency& x) {// 把currency 的值插入到输出流 long a = x.amount; if (a < 0) {out << '-' ; a = -a;} long d = a / 100; // 美元 out << '<< d << '.' ; int c = a - d * 100; // 美分 if (c < 10) out << "0"; out << c; return out; }
数据成员应尽量保持为p r i v a t e成员。通过增加保护类成员来访问和修改数据成员的值,派生类可以间接访问基类的数据成员。同时,可以修改基类的实现细节而不会影响派生类。
#ifndef, #define和# e n d i f语句
在文件头,必须放上如下语句:
#ifndef Currency_
#define Currency_
而在文件尾需要放上语句:
# endif
这些语句确保Currencyy的代码仅被程序包含(Include)和编译一次.
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。