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

2016-02-19 18:35 4 1 收藏

想要天天向上,就要懂得享受学习。图老师为大家推荐C++箴言:声明为非成员函数的时机,精彩的内容需要你们用心的阅读。还在等什么快点来看看吧!

【 tulaoshi.com - 编程语言 】


  我谈到让一个类支持隐式类型转换通常是一个不好的主意。当然,这条规则有一些例外,最普通的一种就是在创建数值类型时。例如,假如你设计一个用来表现有理数的类,答应从整数到有理数的隐式转换看上去并非不合理。这的确不比 C++ 的内建类型从 int 到 double 的转换更不合理(而且比 C++ 的内建类型从 double 到 int 的转换合理得多)。在这种情况下,你可以用这种方法开始你的 Rational 类:
  
  class Rational {
   public:
  Rational(int numerator = 0, // ctor is deliberately not eXPlicit;
  int denominator = 1); // allows implicit int-to-Rational
  // conversions
  
  int numerator() const; // Accessors for numerator and
  int denominator() const; // denominator - see Item 22
  
   private:
  ...
  };
  你知道你应该支持类似加,乘等算术运算,但是你不确定你应该通过成员函数还是非成员函数,或者,非成员的友元函数来实现它们。你的直觉告诉你,当你拿不准的时候,你应该坚持面向对象。你知道这些,于是表示,有理数的乘法与 Rational 类相关,所以在 Rational 类内部为有理数实现 operator* 似乎更加正常。与直觉不符,将函数放置在它们所关联的类的内部的主意有时候与面向对象的原则正好相反,但是让我们将它放到一边,来研究一下将 operator* 作为 Rational 的一个成员函数的主意:
  
  class Rational {
  public:
  ...
  
  const Rational operator*(const Rational& rhs) const;
  };
  (假如你不能确定为什么这个函数声明为这个样子——返回一个 const by-value 的结果,却持有一个 reference-to-const 作为它的参数。)
  
  这个设计让你在有理数相乘时不费吹灰之力:
  
  Rational oneEighth(1, 8);
  Rational oneHalf(1, 2);
  
  Rational result = oneHalf * oneEighth; // fine
  
  result = result * oneEighth; // fine
  但是你并不感到满足。你还希望支持混合模式的操作,以便让 Rationals 能够和其它类型(例如,int)相乘。究竟,很少有事情像两个数相乘那么正常,即使它们碰巧是数字的不同类型。
  
  当你试图做混合模式的算术运算时,可是,你发现只有一半时间它能工作:
  
  result = oneHalf * 2; // fine
  result = 2 * oneHalf; // error!
  这是一个不好的征兆。乘法必须是可交换的,记得吗?
  
  当你重写最后两个例子为功能等价的另一种形式时,问题的

来源:http://www.tulaoshi.com/n/20160219/1618261.html

延伸阅读
在名字空间中声明类和成员函数 赵湘宁     虽然很多程序员都熟悉名字空间的概念,但他们常常都是被动地使用名字空间。也就是说他们使用的是第三方定义的成员(如标准库的类和函数),而不是在名字空间中声明自己的类和函数。本文拟讨论如何在名字空间中声明自己的类和函数,以及如何在程序中使用它们。 ...
函数参数的求值顺序 当一个函数带有多个参数时,C++语言没有规定在函数调用时实参的求值顺序。而编译器根据对代码进行优化的需要自行规定对实参的求值顺序。 !-- frame contents -- !-- /frame contents -- 有的编译器规定自左至右,有的编译器规定自右至左,这种对求值顺序的不同规定,对一般参数来讲没有影响。但是,假...
函数存放在内存的代码区域内,它们同样有地址,我们如何能获得函数的地址呢? 假如我们有一个int test(int a)的函数,那么,它的地址就是函数的名字,这一点如同数组一样,数组的名字就是数组的起始地址。 !-- frame contents -- !-- /frame contents -- 定义一个指向函数的指针用如下的形式,以上面的test()为例: ...
你不应该在构造或析构期间调用虚函数,因为这样的调用不会如你想象那样工作,而且它们做的事情保证会让你很郁闷。如果你转为 Java 或 C# 程序员,也请你密切关注本文,因为在 C++ 急转弯的地方,那些语言也紧急转了一个弯。 假设你有一套模拟股票处理的类层次结构,例如,购入流程,出售流程等。对这样的处理来说可以核查是非常重要的,所...
C++ 的规则设计为保证不会发生类型错误。在理论上,假如你的程序想顺利地通过编译,你就不应该试图对任何对象做任何不安全的或无意义的操作。这是一个非常有价值的保证,你不应该轻易地放弃它。 !-- frame contents -- !-- /frame contents -- 不幸的是,强制转型破坏了类型系统。它会引起各种各样的麻烦,其中一些...

经验教程

607

收藏

40
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部