这是Effective C++中第24个原则,即非成员函数能够完美解决题目中所叙述的情景。
作者以一个有理数类的例子来诠释本原则所述内容。这个例子大致是这样的,这个有理数类有一个带有默认值参数的构造函数,并且也有一个重载的乘法操作符,并且这个重载操作符函数只接受一个有理数类的对象。现在在它参数的位置上放上一个整数,因为构造函数并非显示,所以它允许将这个整数隐式转换成该类的类型而参与运算。
但是奇怪的现象来了,因为这个重载操作符是单目操作符,这时出现了一个赋值语句,
这个就是这个单目操作符,oneHalf是一个有理数类对象,2是整数,2可以被隐式转换成有理数类型。但是下面这个表达式
从逻辑上将实现的功能是一样的,但是它确报错,这是为啥呢?那是因为这个的函数原型如下所示:
因为2并不在参数列表中,根本不存在类型转换,而又因为它要求的是两个有理数类型参与运算,因此2压根不符合类型要求,所以会报错。而这就是所谓的只有被列于参数列表内,这个参数才是隐式转换的合格参与者。
那这里你一定会冒出一个疑问,既然参数列表里面只有一个参数,那你就改写一下这个重载操作符的函数呗,这样两个参数不就都能进行隐式转换了吗?嗯,这个想法是好的,不过类中的重载操作符不支持两个参数的形式,请看下面的图示:
但是非成员函数的重载操作符函数却能支持两个参数的形式,这样两个参数都能进行隐式转换了。
那么为什么不把非成员函数设成有原函数呢?那是因为有原函数的存在极大地破坏了封装特性,不符合面向对象的思想,乱用的话会带来很大麻烦,所以能不用就不用。