-
二进制运算符=(赋值),[](数组订阅),->(成员访问)以及n元()(函数调用)运算符必须始终实现为成员函数,因为语言的语法要求它们。
-
可以将其他运算符实现为成员或非成员。但是,其中一些通常必须实现为非成员函数,因为您无法修改其左操作数。其中最突出的是输入和输出运算符<<和>>,其左操作数是标准库中的流类,您不能更改它们。
对于必须选择将其实现为成员函数或非成员函数的所有运算符,请使用以下经验法则来确定:
-
如果它是一元运算符,请将其实现为成员函数。
-
如果二进制运算符将两个操作数均等地对待(使它们不变),则将该运算符实现为非成员函数。
-
如果二进制运算符不能平等地对待其两个操作数(通常会更改其左操作数),则如果它必须访问该操作数的私有部分,使其成为其左操作数类型的成员函数可能会很有用。
当然,与所有经验法则一样,也有例外。如果你有类型
enum Month {Jan, Feb, …, Nov, Dec}
并且您想为其重载递增和递减运算符,则不能作为成员函数来执行此操作,因为在C ++中,枚举类型不能具有成员函数。因此,您必须将其作为自由函数进行重载。和operator<()嵌套类模板中的类模板是写起来更简单,当作为类定义的成员函数内联方式完成阅读。但是这些确实是罕见的例外。
(但是,如果您创建异常,不要忘记操作数的保存性问题,对于成员函数来说,操作数变成了隐式的this参数。如果作为非成员函数的操作符将其最左边的参数作为const引用,则作为成员函数的相同操作符需要在最后有一个const,从而使*成为const引用。)