Effective C++读书笔记之若所有参数皆需类型转换,请为此采用non-member函数

举个例子来说明我们这次要面对的问题:
 设计一个class用来表现有理数,它应该支持隐式类型转换,虽然我们说令classws支持隐式类型转换通常是个不好的主意。这是为了我们设计的类可以和内置类型进行运算。例如和整型。
 class Rational {
 pbulic:
  Rational(int numerator = 0, int denominator = 1); //注意这个构造函数不为explicit
  int numerator() const;
  int denominator() const;   //两个接口 提供对成员的访问
 priavte:
  .... 
 };
 现在我们想这个class可以支持运算如加法等。问题就来了,这个operator*函数声明为member函数好呢,还是声明为non-member函数好呢?我们通过分别分析这两个函数来给出答案。
 1) member函数实现
 class Rational {
 public:
  .....
  const Rational operator* (const Rational& rhs) const;
 };
 这个设计可以使你能够将两个有理数以最自在的方式相乘,例如:
 Rational oneEighth(1,8);
 Rational oneHalf(1,2);
 Rational result = oneHalf * oneEighth;   //这样的调用很好
 可是当我们希望一个有理数和一个int的数相乘时出现了问题,
 result = oneHalf * 2;    //很好
 result = 2 * oneHalf;    //错误
 写成函数形式就可以看到问题:
 result = oneHalf.operator*(2);  //成功
 result = 2.operator*(ontHalf);  //错误
 operator*函数在int中没有上面class中定义形式,所以不能通过编译。这时编译器也会尝试寻找non-member operator*函数。可是本例没有声明这样的函数,所以查找失败。
 为什么第一个可以成功呢?2也不是一个Rational类型的对象。这是因为编译器为这个2进行了隐式类型转换。
 为什么第一个可以发生隐式类型转换,第二个调用不可以呢?这是因为第一个调用2是作为参数,而第二个不是。
 结论是,只有当参数被列于参数列内,这个参数才是隐式类型转换的合格参与者。也就是说它才可以发生隐式类型转换。
 可是作为member函数只能接收一个参数,而我们这里需要两个参数都需要能发生隐式类型转换。所以唯一的办法就是使用non-member函数。
 1) non-member函数实现
 class Rational { ... };
 const Rational operator* (const Rational& lhs, const Rational& rhs) //一个non-member函数
 {
  return Rational(lhs.numerator() * rhs.numerator(),
   lhs.denominator()* rhs.denominator());
 }
 result = oneHalf * 2;    //很好
 result = 2 * oneHalf;    //没问题了 通过编译
 这时还有一个问题,是不是该把这个函数声明为friend函数?
 答案是否定的。请记住无论何时如果你可以避免friend函数就该避免,因为就像真实世界一样,朋友带来的麻烦往往多过其价值。
 总结:
 如果你需要为某个函数的所有参数(包括被this指针所指的那个隐喻参数)进行类型转换,那么这个函数必须是个non-member. 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值