第 8章 运 算 符 重 载
8.1 概 述
8.2 运算符重载的一般规则
8.3 一些特殊操作符的重载运算符重载就是给已有运算符赋予更多的含义。通过重新定义运算符,使它能够用于特定类的对象执行特定的功能。运算符重载提供了重新定义语言、扩展语言的能力,使程序更加容易阅读和调试。
8.1 概 述运算符通常是针对类中的私有成员进行操作,因此重载运算符应该能够访问类中的私有成员,所以运算符重载一般采用成员函数或友元函数的方式 。 运算符重载的过程是将现有运算符与成员函数或友元函数相关联,使得该运算符具有将该类的对象用作其操作数的能力 。
如:
if (obj1<=obj2) { …… }
其中 obj1和 obj2为类的对象,对象的比较运算可在成员函数中定义或在友元中定义,
并与比较运算符关联 。 编译器可以通过检查运算符数据类型来区分重载的运算符,
运算符重载是多态性的一种形式,即运算符多态性 。
8.2 运算符重载的一般规则运算符重载具有以下原则:
( 1) 重载的运算符是 C++中已经存在的运算符,不能够主观创造 。
( 2) 运算符重载不能改变运算符的语法结构,即操作数的个数 。
( 3) 运算符重载不能改变 C++语言中已定义的运算符的优先顺序和结合性 。
( 4) 运算符重载一般不改变运算符功能 。
( 5) 不能重载的运算符有,sizeof()运算符;
成员运算符 (.);指向成员的指针运算符 (*);
作用域运算符 (::);条件运算符 (?:)。
8.3 一些特殊操作符的重载运算符重载函数是指含有实际的重载运算符的函数,一般采用两种形式:重载为类的成员函数形式和友元函数形式。
8.3.1 一元运算符重载
8.3.1.1 重载为类的成员函数将运算符重载函数说明为类的成员函数的格式如下:
<类型 > operator < 运算符 >( < 参数列表 >)
要重载的运算符必须置于关键字 operator之后 。
【 例 8.1】 重载运算符 ++。
class Point
{
private:
int xcoord;
int ycoord;
public:
Point (){xcoord =0; ycoord =0;}
void operator++(){ ++xcoord; ++ ycoord;}
};
void main()
{
Point obj1;
obj1++; //使 xcoord,ycoord
增加 1
++obj1; //使 xcoord,ycoord
增加 2
}
8.3.1.2 重载为类的友元函数将运算符重载函数说明为类的友元函数的格式如下:
<类型 > operator < 运算符 >( < 参数列表 >)
必须在类的定义中说明该运算符重载函数为类的友元函数 。
【 例 8.2】 用友元函数重载运算符 ++。
#include "iostream.h"
class Point
{
private:
int xcoord;
int ycoord;
public:
Point() //无参数构造函数
{
xcoord = 0; ycoord=0;
}
Point(int x,int y) //单一参数构造函数
{
xcoord = x;
ycoord =y;
}
void display(){cout<<,(”<< xcoord
<<”,”<<ycoord<<”)”<<endl;}
friend Point operator++(Point &);
//前缀自增
friend Point operator++(Point &,int);
//后缀自增
};
Point operator++( Point &e)
{
return Point (++e,xcoord,++e,ycoord);
}
Point operator++( Point &e,int)
{
return Point (e,xcoord ++,e,ycoord ++);
}
void main()
{
Point p1(10,10),p2;
p2=p1++;
p1.display();
p2.display();
p2=++p1;
p1.display();
p2.display();
}
程序运行结果为:
(11,11)
(10,10)
(12,12)
(12,12)
8.3.2 二元运算符重载
8.3.2.1 二元算术运算符重载
【 例 8.3】 加法运算符重载
Point Point::operator+(Point a)
{
Point p; //临时对象
p.xcoord= xcoord+ a,xcoord ;
p.ycoord= ycoord+ a,ycoord ;
return p;
//返回临时对象
}
【 例 8.4】 为字符串重载 +运算符 。
String String::operator+(String ss)
{
String temp;
//声明一个临时字符串 temp
strcpy(temp.str,str);
//将该字符串复制到 temp
strcat(temp.str,ss.str);
//参数字符串相加
return temp;
//返回 temp字符串
}
按以下方式使用:
String s1 = "Welcome";
String s2 = "to C++";
String s3;
s3 = s1 + s2;
【 例 8.5】 重载复合赋值运算符 。
void Point::operator+=(Point a)
{
xcoord += a.xcoord;
ycoord += a.ycoord;
}
8.3.2.2 重载比较和逻辑运算符比较和逻辑运算符是二元运算符,二元运算符需要两个对象才能进行比较 。 可重载的比较运算符包括 <,<=,>,>=,==和 !=。
可重载的逻辑运算符包括 &&和 ||。 例如:
int String::operator>(String ss)
{
return(strcmp(str,ss.str));
}
8.3.2.3 重载赋值运算符
【 例 8.6】 分析下面程序执行情况 。
class String
{
private:
char *str;
public:
String(char *s = "")
{
int length = strlen(s);
str = new char[length+1];
strcpy(str,s);
}
~String() //析构函数
{
delete[] str;
}
void display()
{
cout<<str;
}
};
void main()
{
String s1("Welcome to C++ world \n");
String s2;
s2 = s1;
s1.display();
s2.display();
}
8.1 概 述
8.2 运算符重载的一般规则
8.3 一些特殊操作符的重载运算符重载就是给已有运算符赋予更多的含义。通过重新定义运算符,使它能够用于特定类的对象执行特定的功能。运算符重载提供了重新定义语言、扩展语言的能力,使程序更加容易阅读和调试。
8.1 概 述运算符通常是针对类中的私有成员进行操作,因此重载运算符应该能够访问类中的私有成员,所以运算符重载一般采用成员函数或友元函数的方式 。 运算符重载的过程是将现有运算符与成员函数或友元函数相关联,使得该运算符具有将该类的对象用作其操作数的能力 。
如:
if (obj1<=obj2) { …… }
其中 obj1和 obj2为类的对象,对象的比较运算可在成员函数中定义或在友元中定义,
并与比较运算符关联 。 编译器可以通过检查运算符数据类型来区分重载的运算符,
运算符重载是多态性的一种形式,即运算符多态性 。
8.2 运算符重载的一般规则运算符重载具有以下原则:
( 1) 重载的运算符是 C++中已经存在的运算符,不能够主观创造 。
( 2) 运算符重载不能改变运算符的语法结构,即操作数的个数 。
( 3) 运算符重载不能改变 C++语言中已定义的运算符的优先顺序和结合性 。
( 4) 运算符重载一般不改变运算符功能 。
( 5) 不能重载的运算符有,sizeof()运算符;
成员运算符 (.);指向成员的指针运算符 (*);
作用域运算符 (::);条件运算符 (?:)。
8.3 一些特殊操作符的重载运算符重载函数是指含有实际的重载运算符的函数,一般采用两种形式:重载为类的成员函数形式和友元函数形式。
8.3.1 一元运算符重载
8.3.1.1 重载为类的成员函数将运算符重载函数说明为类的成员函数的格式如下:
<类型 > operator < 运算符 >( < 参数列表 >)
要重载的运算符必须置于关键字 operator之后 。
【 例 8.1】 重载运算符 ++。
class Point
{
private:
int xcoord;
int ycoord;
public:
Point (){xcoord =0; ycoord =0;}
void operator++(){ ++xcoord; ++ ycoord;}
};
void main()
{
Point obj1;
obj1++; //使 xcoord,ycoord
增加 1
++obj1; //使 xcoord,ycoord
增加 2
}
8.3.1.2 重载为类的友元函数将运算符重载函数说明为类的友元函数的格式如下:
<类型 > operator < 运算符 >( < 参数列表 >)
必须在类的定义中说明该运算符重载函数为类的友元函数 。
【 例 8.2】 用友元函数重载运算符 ++。
#include "iostream.h"
class Point
{
private:
int xcoord;
int ycoord;
public:
Point() //无参数构造函数
{
xcoord = 0; ycoord=0;
}
Point(int x,int y) //单一参数构造函数
{
xcoord = x;
ycoord =y;
}
void display(){cout<<,(”<< xcoord
<<”,”<<ycoord<<”)”<<endl;}
friend Point operator++(Point &);
//前缀自增
friend Point operator++(Point &,int);
//后缀自增
};
Point operator++( Point &e)
{
return Point (++e,xcoord,++e,ycoord);
}
Point operator++( Point &e,int)
{
return Point (e,xcoord ++,e,ycoord ++);
}
void main()
{
Point p1(10,10),p2;
p2=p1++;
p1.display();
p2.display();
p2=++p1;
p1.display();
p2.display();
}
程序运行结果为:
(11,11)
(10,10)
(12,12)
(12,12)
8.3.2 二元运算符重载
8.3.2.1 二元算术运算符重载
【 例 8.3】 加法运算符重载
Point Point::operator+(Point a)
{
Point p; //临时对象
p.xcoord= xcoord+ a,xcoord ;
p.ycoord= ycoord+ a,ycoord ;
return p;
//返回临时对象
}
【 例 8.4】 为字符串重载 +运算符 。
String String::operator+(String ss)
{
String temp;
//声明一个临时字符串 temp
strcpy(temp.str,str);
//将该字符串复制到 temp
strcat(temp.str,ss.str);
//参数字符串相加
return temp;
//返回 temp字符串
}
按以下方式使用:
String s1 = "Welcome";
String s2 = "to C++";
String s3;
s3 = s1 + s2;
【 例 8.5】 重载复合赋值运算符 。
void Point::operator+=(Point a)
{
xcoord += a.xcoord;
ycoord += a.ycoord;
}
8.3.2.2 重载比较和逻辑运算符比较和逻辑运算符是二元运算符,二元运算符需要两个对象才能进行比较 。 可重载的比较运算符包括 <,<=,>,>=,==和 !=。
可重载的逻辑运算符包括 &&和 ||。 例如:
int String::operator>(String ss)
{
return(strcmp(str,ss.str));
}
8.3.2.3 重载赋值运算符
【 例 8.6】 分析下面程序执行情况 。
class String
{
private:
char *str;
public:
String(char *s = "")
{
int length = strlen(s);
str = new char[length+1];
strcpy(str,s);
}
~String() //析构函数
{
delete[] str;
}
void display()
{
cout<<str;
}
};
void main()
{
String s1("Welcome to C++ world \n");
String s2;
s2 = s1;
s1.display();
s2.display();
}