12.4 非成员运算符

在前面的一些例子里,运算符可能是成员运算符或非成员运算符,这似乎没有多大差异。这样就会出现一个问题:“应该选择哪一种?”总的来说,如果没有什么差异,它们应该是成员运算符。这样做强调了运算符和类的联合。当左侧操作数是当前类的对象时,运算符会工作得很好。

但有时左侧运算符是别的类的对象。这种情况通常出现在为输入输出流重载operator<<和>>时。因为输入输出流是一个基本C++库,我们将有可能想为定义的大部分类重载运算符,所以这个过程是值得记住的:

12.4 非成员运算符 - 图1

12.4 非成员运算符 - 图2

这个类还包含重载operator[],这个运算符在数组里返回了一个合法值的引用。因为一个引用被返回,所以下面的表达式:

12.4 非成员运算符 - 图3

看起来不仅比使用指针更规范些,而且它也达到了预期的效果。

被重载的移位运算符通过引用方式传递和返回,所以运算将影响外部对象。在函数定义中,表达式如

12.4 非成员运算符 - 图4

会使现有的重载运算符函数被调用(即那些定义在<iostream>中的)。在这种情况下,被调用的函数是ostream&operator<<(ostream&,int),这是因为ia.i[j]是一个int值。

一旦所有的动作在istream或ostream上完成,它将被返回,因此它可被用于更复杂的表达式。

在main()中,iostream的一种新类型被使用:stringstream(在<sstream>中声明)。该类包含一个string(正如此处显示的,它可以由一个char数组创建)并且把它转化为一个iostream。在上面的例子中,这意味着在不打开一个文件或在命令行中键入数据的情况下,移位运算符可以被测试。

这个例子使用的是插入符和提取符的标准形式。如果想为自己的类创建一个集合,可以拷贝这个函数署名并返回以上的类型,且遵从该函数体的形式。

12.4.1 基本方针

Murray[1]为在成员和非成员之间的选择提出了如下的方针:

12.4 非成员运算符 - 图5

[1]参见Rob Murray所著《C++Strategies&Tactics》(Addison-Wesley),1993,第47页。