定义一个重载的运算符是这个函数的名字必须以operator开头。
运算符重载函数的一般形式为:
类型 类名::operator 重载的运算符 (参数列表)
{
相关操作;
}
它的参数个数由以下两个因素决定:
- 该操作符是一元操作符还是二元操作符
- 它是被定义为全局函数还是一个成员函数。如果是全局函数,那么对于一元操作符它的参数个数就是1个(后置++、–除外),二元操作符的参数个数是2个;如果是成员函数,那么对于一元操作符的参数个数为0,二元操作符的参数个数为1。这是由于该类本身也作为一个操作数参与计算,所以成员函数的参数要比全局函数的参数个数少1。
注意:
- 当运算符函数是全局函数时,需要在类中将该函数说明为友员。
- 虽然运算符重载可以改变运算符原来的行为,但是它并不能改变运算符的优先级、结合性、操作数的个数。也不能创建新的运算符,只能重载现有的运算符。
- 运算符重载函数的参数至少有一个必须是自定义类型。
- 在重载运算符()、[]、->或者=时,运算符重载函数必须声明为类的一个成员。对于其他的运算符,运算符重载函数可以是成员函数或者友元函数。
可以重载和不可重载的运算符
- =运算符的重载
赋值运算符“=”只能通过说明一个非静态成员函数来重载。
赋值运算符是唯一的一个不能被继承的运算符函数。
例如对复数类中赋值运算符重载为如下函数:
Complex& Complex::operator=(const Complex& c)
{
if(this==&c) return *this; //如果对本对象给自己赋值,直接返回本对象
realpart=c.realpart;
imagpart=c.imagpart;
return *this;
}
一般来说,赋值运算符应该返回本对象的引用*this,目的在于可以使赋值运算级联为更大的表达式。请看下面的语句:
int a, b=5;
(a=b)++;
- ++和–运算符的重载
++,–,可以是前缀操作符,也可以是后缀操作符,为了区分是前缀运算符还是后缀运算符,在重载时将后缀操作符看作二元操作符,增加一个int型参数,但该参数并不参加运算,只是用来区分重载函数。
下面是++和–运算符的重载的例子:
#include <iostream.h>
class CTest {
int t1,t2;
public:
CTest (int,int);
CTest operator++(); // 前缀
CTest operator++(int); // 后缀
CTest operator--(); // 前缀
CTest operator--(int); // 后缀
void Display() const;
};
//类成员函数的实现
CTest::CTest(int a,int b){ t1=a; t2=b;}
CTest CTest::operator++()
{
cout << "++test\n";
t1++;t2++;
return *this;
}
CTest CTest::operator++(int)
{
cout << "test++\n";
int tmp1=t1;
int tmp2=t2;
t1++;t2++;
return CTest (tmp1,tmp2);
}
CTest CTest::operator--()
{
cout << "--test\n";
--t1;--t2;
return *this;
}
CTest CTest::operator--(int)
{
cout << "test--\n";
int tmp1=t1;
int tmp2=t2;
--t1;--t2;
return CTest (tmp1,tmp2);
}
void CTest::Display() const
{
cout<<"("<<t1<<","<<t2<<")";
}
//主程序
int main()
{
CTest b(3,4);
b.Display(); cout<<endl;
++b;
b.Display(); cout<<endl;
b++;
b.Display(); cout<<endl;
--b;
b.Display(); cout<<endl;
b--;
b.Display(); cout<<endl;
return 0;
}
- []的重载
[]运算符一般是用在数组中来标识数组元素的位置,是可以出现在等号左边作为左值的。重载函数operator[]的返回值类型也应该是引用类型。其中对于数组数据的赋值和取值就是通过[]运算符的重载来实现的。
例:自定义一个数组类,实现“[]”运算符重载
class MyArray{
public:
int& operator[](int i); //重载“[]”运算符
private:
int array[size];
};
实现“[]”运算符重载:
int& MyArray::operator[](int i){
if(i>=size||i<0){ //防止下标越界
cout<<"下标越界!"<<endl;
exit(1);
}
return array[i]; //返回本对象数组元素的值
}
- 总结:
(1)运算符重载可以改变C++语言所提供的大多数运算符的含义。
(2)运算符重载时必须声明为成员函数或者友元函数。
(3)重载运算符允许使用一种非常自然的表达方式来表达用户自定义类型的数据之间的关系。
(4)运算符重载不能改变运算符的优先级和结合性,不能改变运算符操作数的个数,也不能增加新的运算符。重载运算符时,要使运算符的含义与数学中的规定和人们的常识相符,并且对函数的功能给予必要的说明。否则就有可能将运算符的含义隐藏在难以理解的代码中,使人难以理解。