1.运算符重载的六个注意事项:
(1).重载运算符函数的参数个数,应该与参与这个运算符的运算对象数量一样多,但是如果是成员函数,则参数数量要少一个,因为第一个参数是this。例如:
#include<iostream>
using namespace std;
class Test
{
public:
int value;
int operator+(const Test &v ) //重载为成员函数
return this->value+v.value; //等同于value+v.value;
};
int operator+(const Test &v1,const Test &v2)
{
return v1.value+v2.value;
}
int main()
{
Test a,b;
a.value=5;
b.value=6;
printf("a+b=%d\n",a+b);
return 0;
}
(2).运算符重载函数的参数至少要有一个类的成员(或者类类型)作为参数,而不能都是内置类型(会导致编译错误)。例如int operator+(int, int)是不行的,因为int是内置类型。内置类型的操作符明显是不能重载的,比如重载了int型的+运算符,那程序其他地方的int加法都会使用重载的函数,这明显是不行的。
(3).运算符可以像普通函数一样调用。
(4).有些运算符是不适合重载的;(,、&、&&、||等)。
(5).必须作为成员函数的重载运算符:=、[]、()、->,否则会编译错误。
(6).重载运算符函数是成员函数时,其实就是运算符左侧的对象调用的这个运算符,所以左侧对象必须是运算符所属类的一个对象。
2.输入输出运算符重载:
(1).“<<”和“>>”表示移位操作,在IO标准库(iostream库)重载了这两个运算符来处理输入和输出,自己重载这两个运算符的目的就是要用在输出自定义的类的时候。
(2).如果要与iostream库兼容输入输出操作,则自己重载的时候必须作为非成员函数,这个是因为如果作为成员函数,则左侧的操作对象应该是这个类的对象,这样就不能兼容iostream库的输入输出操作。当然非要重载为成员函数,也是可以编译通过的,只不过是不能兼容标准库iostream的输入输出操作而已。
(3).因为IO运算符通常要访问类的所有成员,所以一般是把重载的非成员函数声明为类的友元函数。
3.递增递减运算符重载
(1).递增和递减一般是改变对象的状态,所以一般是重载为成员函数。
(2).重载递增递减,一定要和指针的递增递减区分开。因为这里的重载操作的是对象,而不是指针(由于指针是内置类型,指针的递增递减是无法重载的),所以一般情况的递增递减是操作对象内部的成员变量。
(3).递增和递减分为前置和后置情况,a = ++b;(前置), a = b++;(后置)。因为符号一样,所以给后置版本加一个int形参作为区分,这个形参是0,但是在函数体中是用不到的,只是为了区分前置后置。例如:
#include<stdio.h>
#include<stdlib.h>
#include<string>
#intclude<iostream>
using namespace std;
class Test
{
int value;
//前置递增就是增加当前对象的pos的值,并且返回当前对象(递增之后的对象)
Test operator++()
{
valued++;
return *this;
}
//后置递增就是增加当前对象的pos的值,并且返回增加pos之前的该对象(递增之前的对象)
Test operator++(int)
{
Test ret=*this;
value++; //或者是++this (此时会调用上面的函数)
return ret;
}
};
int main()
{
Test a,b;
a.value=1;
b=a++;
cout<<"b1="<<b.value<<endl; //b1=1;
b=++a;
cout<<"b2="<<b.value<<endl; //b2=3;
}
4.重载函数调用运算符“()”
(1).*类重载了括号运算符,则该类的对象就可以当成函数一样来使用。
(2).这种对象常常用作泛型算法的实参,因为有些泛型算法可以提供自定义的比较函数。例如:
#include<iostream>
using namespace std;
void myprint(const string & str)
{
printf("Priintf :%s\n",str.c_str());
return;
}
class Test
{
int value;
Test()
{
value=0;
}
void operator()(const string &str)
{
printf("Test print : %s\n", s.c_str());
value++;
}
};
int main()
{
vector<string> v;
v.push_back("abc");
v.push_back("def");
for_each(v.begin(),v.end(),myprintf);
Test t;
for_each(v.begin(),v.end(),t); //这里要注意,这个是值传递,传的是a的副本
printf("Test printf value: %d\n", t.value); //所以这个地方的value还是0
t("hhhh");
t("ffffff");
printf("Test printf value: %d\n", t.value); //现在value的值就是2了.
}