运算符重载时的几个关键点:
1. 首先,运算符重载不会改变运算符的优先级和结合性。
2. 运算符的重载不能改变运算符的运算对象数。因此,重载函数的形参个数(包括成员函数的隐式指针this)与运算符的运算对象数相同。
3. 大多数运算符重载函数都可以定义为全局函数(友元函数)或类的成员函数:
当定义为成员函数时:
运算符的运算对象数目比函数形参数目少1,因为成员函数第一个有一个隐藏的this指针作为参数。
当定义为全局函数时:
运算符的运算对象数目与函数形参数目相等。
4. 不能重载的运算符:
类属关系运算符:.
成员指针运算符:.*
sizeof
作用域分辨符:::
三目运算符:?:
5. 如何确定是重载为全局函数还是成员函数
有一些运算符必须要重载为成员函数,因为这些运算符的第一个对象必须是相应类的对象。
下标运算符:[ ] 函数调用运算符:( ) 成员访问运算符:-> 赋值运算符:=
++ 和 – 运算符最好重载为成员函数。
具有两个运算对象且计算结果会产生一个新的对象的运算符最好重载为全局函数。
6. 几种特殊运算符的重载:
(1) :赋值运算符的重载:
一般来讲,需要自定义拷贝构造函数的类也需要自定义赋值运算符重载函数。
注意,赋值运算符要返回运算符的左值。因为,赋值是一个运算,也可以构成一个表达式,该表达式的结果值就是运算符左侧的对象的值。
看一个例子:
http://blog.csdn.net/hyhyl1990/article/details/7957604
(2): 下标运算符的重载:
下标运算符只能为成员函数去重载。
(3): 函数调用运算符重载:
C++把函数调用也看成为一个运算。函数调用运算符必须重载为成员函数。
(4): ++ -- 运算符重载:
比较复杂。这两种运算符都有两种用法,就可以做前缀使用,也可以做后缀使用。但两者形式是一样的,C++在处理时,
规定后缀运算符重载函数接受一个额外的(其实是无用的)int型的参数。使用后缀运算符时,编译器用0作为这个参数的值。
//**************++ --运算符的重载*******************************
class Count
{
friend ostream& operator<< (ostream& os,const Count& c); //重载为类的友元
friend istream& operator>> (istream& is,Count& c); //重载为类的友元
private:
double num;
public:
Count(){}
Count(double x){num=x;}
Count& operator++ (); //前缀的++运算符
Count operator++ (int notuse); //后缀的++运算符
void display(){cout<<"num: "<<num<<endl;}
};
Count& Count::operator++ ()
{
this->num++;
return *this;
}
Count Count::operator++ (int notuse)
{
Count tmp=*this;
this->num++;
return tmp;
}
(5): 输入/输出运算符重载:
流提取运算符:>>
流插入运算符:<<
C++规定输入/输出运算符必须被重载为全局函数,一般应将此全局函数声明为类的友元。
<< 和 >> 被看做是二元运算符,左结合。以cout<<x为例,两个运算对象分别是cout和x。结果是cout。
两个重载原型是:
ostream& operator<<(ostream& os,const ClassType& c)
{
os<<要输出的内容;
return os;
}
istream& operator>>(istream& is,Count& c)
{
is>>要输入的内容;
return is;
}
//************************输入/输出运算符的重载*****************
ostream& operator<< (ostream& os,const Count& c)
{
os<<"num: "<<c.num<<endl;
return os;
}
istream& operator>> (istream& is,Count& c)
{
is>>c.num;
return is;
}