一般我们应该怎样决定把一个操作符声明为了类成员还是名字空间成员呢?在某些情况下,程序员是没有选择的余地。
1、如果一个重载操作符是类成员,那么只有当跟它一起被使用的左操作数是该类的对象时,它才被调用。如果该操作符的左操作数必须是其他的类型,那么重载操作符必须是名字空间成员。
2、C++要求,赋值(=)、下标([ ])、调用(())和成员访问箭头(->)操作符必须被定义为类成员操作。任何把这些操作符定义为名字空间成员的定义都会被标记为编译时刻错误。如果操作符的有个参数是类类型,那么可以将该操作符定义为名字空间成员。例如:
//错误:必须是类string的成员
char& operator[](string&, int i) ;
//正确:是类string的成员
char& operator[](int i) const ;
//将等于(==)操作符声明为类成员
bool operator ==(const string& str) const ;
//因为==操作符有一个参数是string类型,则可以将其声明为名字空间类型。
bool operator ==(const string& str1,const string& str2) ;
3、重载的操作符声明为成员函数与声明为非成员的区别:
//将递增和递减操作符声明为类Screen的成员函数
class ScreenPtr
{
public:
Screen& operator++() ; //前置操作符
Screen& operator--() ;
Screen& operator++(int) ; //后置操作符
Screen& operator--(int) ;
// ...
};
//将递增和递减操作符声明为类Screen的非成员函数
class ScrennPtr
{
public:
friend Screen& operator++( ScreenPtr& ) ; //前置操作符
friend Screen& operator--( ScreenPtr& ) ;
friend Screen& operator++( Screen&, int ) ; //后置操作符
friend Screen& operator--( Screen&, int ) ;
};
从上面的例子中,我们可以看到重载操作符时将其声明为非成员函数时,需要在其操作符后面的参数表中需声明调用该操作符的对象,而将其声明为成员函数时,则不用在其操作符的参数表声明调用其的对象。因为该重载操作符的函数是类的成员函数,那么成员函数的调用是由该类的对象来调用。所以不用另外再声明了。