运算符重载

来源:互联网 发布:iphone数据备份 编辑:程序博客网 时间:2024/05/21 21:47

实现函数运算符的实质:编写一个函数,该函数以“operator运算符号”为函数名,其定义了重载的运算符将要执行的操作。(给自己的类进行运算)

运算符重载有两种形式:重载为类的成员函数  重载为类的友元函数

(1)重载为类的成员函数:

         双目运算符:一个参数(左操作数是访问该运算符对象本身的数据,由this指针给出,右操作数由参数给出)

                               显示调用:aa.operator+(bb);

                               隐式调用:aa+bb;

        单目运算符:0个参数(操作数是访问该运算符对象本身的数据,由this指针给出)

                               显示调用:aa.operator++();

                               隐式调用:++aa;

(2)重载为类的友元函数:

         双目运算符:两个参数(重载为友元函数时,没有this指针,两个操作数由参数给出)

                               显示调用:operator+(aa,bb);

                               隐式调用:aa+bb;

        单目运算符:一个参数

                               显示调用:operator++(aa);

                               隐式调用:++aa;

"++""--"重载:

(1)operatot++(),operator--():重载前置运算符(++a),且为单目运算符

(2)operator++(int),operator--(int):重载后置运算符(a++),且为双目运算符

特殊运算符重载:

?=、[]、()、->以及所有的类型转换运算符只能作为成员函数重载。
如果允许第一操作数不是同类对象,而是其他数据类型,则只能作为非成员函数重载(如输入输出流运算符>>和<<
就是这样的情况)。

不能重载的运算符只有5个:

.         (成员访问运算符)

.*       (成员指针访问运算符)

∷        (域运算符)

sizeof   (长度运算符)

?:        (条件运算符)

练习:

下面的程序定义了一个简单的SmallInt类,用来表示从-128到127之间的整数。类的唯一的数据成员val存放一个-128到127(包含-128和127这两个数)之间的整数,为了方便,类SmallInt还重载了一些运算符。阅读SmallInt的定义,回答题目后面的问题。

 

class SmallInt{

public:

         SmallInt(int i=0);

         //重载插入和抽取运算符

         friend ostream &operator<<(ostream&os,const SmallInt &si);

         friend istream &operator>>(istream &is, SmallInt &si);

         //重载算术运算符

         SmallInt operator+(const SmallInt &si){return SmallInt(val+si.val);}

         SmallInt operator-(const SmallInt &si){return SmallInt(val-si.val);}

         SmallInt operator*(const SmallInt &si){return SmallInt(val*si.val);}

         SmallInt operator/(const SmallInt &si){return SmallInt(val/si.val);}

         //重载比较运算符

         bool operator==(const SmallInt &si){return (val==si.val);}

private:

         char val;

};

 

SmallInt::SmallInt(int i)

{

         while(i>127)

                   i-=256;

         while(i<-128)

                   i+=256;

         val=i;

}

 

ostream &operator<<(ostream &os,const SmallInt &si)

{

         os<<(int)si.val;

         return os;

}

 

istream &operator>>(istream &is,SmallInt &si)

{

         int tmp;

         is>>tmp;

         si=SmallInt(tmp);

         return is;

}

问题1:上面的类定义中,重载的插入运算符和抽取运算符被定义为类的友元函数,能不能将这两个运算符定义为类的成员函数?如果能,写出函数原型,如果不能,说明理由。

答:不能将插入运算符和抽取运算符定义为类的成员函数。
因为这两个运算符对第一个运算数有特殊的要求,即必须分别是ostream和istream类的对象,而不能是用户自己定义的其它类,而类的成员函数默认的第一个参数为指向该类对象的指针类型,所以不符合插入和抽取运算符的要求

 

问题2:为类SmallInt增加一个重载的运算符‘+=’,函数原型:

class SmallInt{

public:

         SmallInt &operator +=(const SmallInt &si);

         //其它函数

private:

         char val;

};

该函数将返回对当前对象的引用。如:

SmallInt si1(20),si2(13);

则表达式:

  si1+=si2

将返回对象si1的引用,并且si1中的的值是si1.val和si2.val的值之和(但必须正规化为在-128至127之间)。

在下面写出重载的运算符+=的实现:

重载的运算符的实现如下:SmallInt &SmallInt::operator+=(const SmallInt &si)

{

         SmallInt tmp(val+si.val); //调用的之前重载的“+”

         val=tmp.val;

         return *this;

}SmallInt &SmallInt::operator+=(const SmallInt &si)

{

         val+=si.val;

         if(val>127)

                   val-=256;

         if(val<-128

                   val=256;

         return *this;

}



原创粉丝点击