c++基本语法4--c++程序设计教程/钱能主编--清华大学出版社...
时间:2010-08-10 来源:y84161838
第十八章 运算符重载
C++规定 . // ::// .* // .- >// ?: 这5个运算符不能重载,也不能创造新运算符。
为什么operator + () 中的参数用引用传递而不用指针传递? 主要为了可读性。
如果只给出一个operator ++ ()定义,那么他一般可用于前缀后缀两种形式。d++和++d不做区别。
一个运算符成员形式,将比非成员形式少一个参数,左边参数是隐含的。
例如:RMB 是一个类,假定operator + ()是其成员函数或不是两种情况下的定义
RMB operator + (RMB& s1 , RMB& s2) //非成员形式
{
unsigned int jf = s1.jf + s2.jf;
unsigned int yuan = s1.yuan + s2.yuan;
RMB result(yuan,jf); //构造一个RMB类实例作为返回值
return result;
}
RMB operator + (RMB& s ) //成员形式
{
unsigned int jf = jf + s.jf;
unsigned int yuan = yuan + s.yuan;
RMB result(yuan,jf); //构造一个RMB类实例作为返回值
return result;
}
C++规定: = , () , [] ,-> 这四种运算符必须为成员形式。
18.5 c++约定,在增量运算符定义中,放上一个整数形参,就是后增量运算符。
前增量与后增量的区别:
使用前增量时,对对象(操作数)进行增量修改,然后再返回该对象 。所以前增量运算符操作时,参数与返回的是同一个对象。这与基本数据类型的前增量操作类似,返回的也是左值。
使用后增量时,必须在增量之前返回原有的对象值。为此,需要创建一个临时对象,存放原有的对象,以便对操作数(对象)进行增量修改时,保存最初的值。后增量操作返回的是原有对象值,不是原有对象,原有对象已经被增量修改,所以,返回的应该是存放原有对象值的临时对象。
#include <iostream>
using namespace std;
class Increase
{
public:Increase(int x):value(x){}
Increase& operator ++ ();
Increase operator ++ (int);
void display()
{
cout<<"the value is "<<value<<endl;
}
private:
int value;
};
Increase& Increase::operator ++ ()
{
value++; //先增量
return *this;//再返回原有对象值
}
Increase Increase::operator ++ (int)
{
Increase temp(*this); //临时对象存放原有对象值
value++ ; //原有对象增量修改
return temp; //返回原有对象值
}
void main()
{
Increase n(20);
n.display();
(n++).display();
n.display();
++n;
n.display();
++(++n);
n.display();
(n++)++;
n.display();
}
后增量运算符中的参数int 只是为了区别前增量和后增量,除此之外没有任何作用。因为定义中,无需使用该参数,所以形参名在定义头中省略。
18.6 转换 运算符
operator 类型名();
她没有返回类型,因为类型名就代表了他的返回类型,故返回类型显得多余。
转换运算符将对象转换成类型名规定的类型。如果没有转换运算符的定义,直接用强制转换是不行的,因为强制转换只能对基本数据类型进行操作,对类类型的操作没有定义的。
转换运算符与转换构造函数(简称转换函数)互逆。例如,RMB(double)转换构造函数将double转换为RMB,而RMB::operator double()经RMB转换成double。
#include <iostream>
using namespace std;
class RMB
{
public:
RMB(double value = 0.0);
operator double()
{
return yuan + jf/100.0 ;
}
void display()
{
cout<<(yuan + jf/100.0)<<endl;
}
protected:
unsigned int yuan;
unsigned int jf;
};
RMB::RMB(double value /* = 0.0 */)
{
yuan = value ;
jf = (value - yuan)*100 + 0.5 ;
}
void main()
{
RMB d1(2.0),d2(1.5) , d3;
d3 = RMB(double(d1)+double(d2)); //显式转换
d3.display();
d3 = d1 + d2;
d3.display();
}
18.7 赋值运算符
#include <iostream>
#include <string>
using namespace std;
class Name
{
public:
Name()
{
pName = 0;
}
Name(char * pn)
{
copyName(pn);
}
Name(Name& s)
{
copyName(s.pName);
}
~Name()
{
deleteName();
}
Name& operator = (Name& s) //赋值运算符
{
deleteName();
copyName(s.pName);
return *this ;
}
void display()
{
cout<<pName<<endl;
}
protected:
void copyName(char* pN);
void deleteName();
char * pName;
};
void Name::copyName(char* pn)
{
pName = new char[strlen(pn)+1];
if(pName)
{
strcpy(pName,pn);
}
}
void Name::deleteName()
{
if(pName)
{
delete pName;
pName = 0;
}
}
void main()
{
Name s("claudette");
Name t("hnu university");
t.display();
t = s;
t.display();
}
如果赋值运算符说明为保护或私有的,则可以将赋值操作限定在类的作用域范围,防止应用程序中使用赋值操作。
//书后习题 18.4
#include <iostream>
using namespace std;
class RMB
{
public:
RMB(unsigned int d,unsigned int c);
RMB operator + (RMB&);
RMB& operator ++ ();
//////////////////////////////////////
RMB& operator += (const RMB&);
RMB& operator += (unsigned int);
RMB& operator -= (const RMB&);
RMB& operator -= (unsigned int);
///////////////////////////////////////
void display()
{
cout<<(yuan+jf/100.0)<<endl ;
}
protected:
unsigned int yuan;
unsigned int jf;
};
RMB::RMB(unsigned int d,unsigned int c)
{
yuan = d;
jf = c;
while(jf>=100)
{
yuan++;
jf -=100;
}
}
RMB RMB::operator+ (RMB& s)
{
unsigned int c = jf+s.jf;
unsigned int d = yuan + s.yuan ;
RMB result(d,c);
return result;
}
RMB& RMB::operator++ ()
{
jf++;
if(jf>=100)
{
jf -=100;
yuan++;
}
return *this;
}
////////////////////////////////////////////////////////////////
RMB& RMB::operator+= (const RMB& rmb)
{
jf +=rmb.jf;
yuan +=rmb.yuan;
if(jf>=100)
{
yuan++;
jf-=100;
}
return *this;
}
RMB& RMB::operator += (unsigned int d)
{
jf +=d;
if(jf>=100)
{
jf-=100;
yuan++;
}
return *this;
}
RMB& RMB::operator-= (const RMB& rmb)
{
int temp_yuan;
int temp_jf;
temp_yuan =yuan - rmb.yuan;
temp_jf =jf - rmb.jf;
if(temp_jf >= 0 && temp_yuan >=0)
{
yuan = temp_yuan;
jf = temp_jf;
}
else if(temp_jf<0 && temp_yuan >0)
{
jf = 100+temp_jf;
yuan = temp_yuan -1;
}
else
{
yuan = 0;
jf = 0;
}
return *this;
}
RMB& RMB::operator -= (unsigned int d)
{
int temp_jf ;
temp_jf = jf - d;
if(temp_jf>=0)
{
jf = temp_jf ;
}
else if(temp_jf<0 && yuan >0)
{
yuan--;
jf = 100+temp_jf ;
}
return *this;
}
/////////////////////////////////////////////////////////////
void main()
{
RMB d1(2,60);
RMB d2(2,50);
RMB d3(0,0);
/* d3 = d1 + d2 ;
++d3;
d3.display();
cout<<"test +=(rmb)"<<endl;
d1+=d2;
d1.display();
cout<<"test +=(double)"<<endl;
d1 +=20;
d1.display();
cout<<"test -=(rmb)"<<endl;
d2 -= d1;
d2.display();
*/ cout<<"test -=(double)"<<endl;
d1 -=70;
d1.display();
/**/
}