C++箴言:声明为非成员函数的时机

C++箴言:声明为非成员函数的时机,第1张

C++箴言:声明为非成员函数的时机,第2张

我提到过让一个类支持隐式类型转换通常不是一个好主意。当然,这个规则也有一些例外。最常见的是在创建数值类型时。例如,如果你设计一个类来表示有理数,那么允许从整数到有理数的隐式转换似乎也不是不合理的。这不比C++内置类型从int到double的转换更不合理(也比C++内置类型从double到int的转换合理得多)。在这种情况下,您可以这样开始您的Rational类:

class Rational {
public:
Rational(int分子= 0,// ctor故意不显式;
int分母= 1);//允许隐式int到Rational
//转换

int分子()常量;//分子和
int分母()常量的访问器;//分母-见第22项

私有:
...
};

你知道应该支持加法、乘法等算术运算,但不确定应该通过成员函数还是非成员函数,或者非成员的朋友来实现。你的直觉告诉你,当你不确定的时候,你应该坚持面向对象。知道了这一点就意味着有理数的乘法和有理类有关,所以在有理类内部实现有理数的运算符*似乎更正常。与直觉相反,将函数放在它们所关联的类中的想法有时与面向对象的原则背道而驰,但是让我们把它放在一边,研究一下使用operator*作为Rational的成员函数的想法:

class Rational {
public:
...

const Rational运算符*(const Rational & RHS)const;
};

(如果您不确定为什么要这样声明这个函数——它返回一个const by-value的结果,但是保存一个对const的引用作为它的参数。)

这种设计使您可以轻松地将有理数相乘:

有理八分之一(1,8);
有理oneHalf(1,2);

有理结果=二分之一*八分之一;//好吧

结果=结果*八分之一;//好吧

但是你不满足。您还希望支持混合模式操作,以便可以将有理数乘以其他类型(例如,int)。毕竟,很少有事情像两个数字相乘那样正常,即使它们碰巧是不同类型的数字。

然而,当您尝试进行混合模式运算时,您会发现它只在一半的时间内有效:

结果=二分之一* 2;//fine
result = 2 * one half;//错误!

这是一个不好的迹象。乘法必须是可换的,记得吗?

当你把最后两个例子改写成另一种形式的功能对等时,问题的根源就变得很明显了:

result = one half . operator *(2);//fine
result = 2 . operator *(one half);//错误!

对象oneHalf是一个包含运算符*的类的实例,因此编译器调用该函数。但是整数2与类无关,所以没有operator*成员函数。编译器还应该查找非成员运算符(即命名空间或全局范围内的运算符),可以按如下方式调用:

结果=运算符*(2,one half);//错误!

但是在这个例子中,没有非成员持有int和Rational操作符*,所以搜索失败。

再看一下那个成功的电话。您会发现它的第二个参数是整数2,而Rational::operator*持有一个Rational对象作为它的参数。这里发生了什么?为什么在一个地方可以,在其他地方不行?

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » C++箴言:声明为非成员函数的时机

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情