C ++中的Fractions类解释

时间:2014-09-10 22:43:58

标签: c++ fractions

有人可以解释一下这段代码中的内容吗?您不必逐行,但总体摘要将非常有用。它类似于其他分数类c ++代码,因此您不必完全引用此代码。

#include<iostream>

using namespace std;

class Fraction

{

  private:

  int num, den;

  public:

  Fraction(int n = 1, int d = 2) : num(n), den(d) { }

  void show() { cout«num«”/”«den; }

  Fraction operator+(Fraction f) const

  { return Fraction(num+f.num, den+f.den); }

  Fraction operator-(Fraction f) const

  { return Fraction(num-f.num, den-f.den); }

  Fraction operator*(Fraction f) const

  { return Fraction(num*f.num, den*f.den); }

  Fraction operator/(Fraction f) const

  {

    int rNum = (f.den*num)/den;

    return (rNum, f.num);

   } 

  friend ostream& operator«(ostream& out, Fraction& f)

  { cout«f.num«”/”«f.den; return out; }

  friend istream& operator»(istream& in, Fraction& f)

  { cout«”\nEnter Numerator: “; cin»f.num; cout«”Enter Denominator: “;

    cin»f.den; cout«f.num«”/”«f.den; return in; }

  int ndMax()

  { return (num<=den) ? num:den; }

  void reduce()

  {

  for(int i = 2; i<=ndMax(); i++)

    if(num%i == 0 && den%i == 0)

    { num = num/i; den = den/i; i = 1; }

  }

}; // 

int main()

{

  Fraction f1(5, 6);

  Fraction f2(80, 1001);

  cout«f1«” and “«f2«endl;

  Fraction f3 = f1/f2;

  f3.reduce(); cout«f3;

  cout«endl;

  return 0;

 }

1 个答案:

答案 0 :(得分:1)

// This declares a dependency on the system module, iostream. Specifically, this code uses the
// system provided objects, cout, and cin, for output and input.
#include <iostream>

// This says if the compiler cannot find a symbol, it should try looking in the namespace, std.
using namespace std;

// This defines a type called, Fraction.
class Fraction {
private:
  // This declares two private member variables, num, and den, presumably representing the
  // numerator and denominator of a fraction. Each object of type Fraction will have its own
  // num and den. Because they are private they cannot be accidentally modified outside the
  // definition of Fraction. They are the module's secret.
  int num, den;

public:
  // This declares a constructor. It uses the default argument notation to actually define
  // three constructor syntaxes. Two arguments may be given, one, or zero. Fraction() = 1/2,
  // Fraction(x) = x/2, and Fraction(x, y) = x/y. A default denominator of 1 would be more
  // normal, especially since this constructor can be used to implicitly convert an int into
  // a Fraction.
  Fraction(int n = 1, int d = 2) : num(n), den(d) { }

  // This function outputs a representation of a Fraction to cout. It repeats the definition
  // of operator<< below, which violates the DRY principle so it should probably be written
  // as: cout << *this;
  void show() {
    cout << num << " / " << den; }

  // This is an operator overload. It allows you to write, Fraction + Fraction. Note that it
  // does not add fractions in the expected way, instead it does a vector addition.
  Fraction operator+(Fraction f) const {
    return Fraction(num + f.num, den + f.den); }

  // Similarly broken.
  Fraction operator-(Fraction f) const {
    return Fraction(num - f.num, den - f.den); }

  // Correct multiplication, although normalizing the fraction is kind of expected.
  Fraction operator*(Fraction f) const {
    return Fraction(num * f.num, den * f.den); }

  // Cannot be bothered to decide if this is correct. Multiplying by the inverse would be the
  // more obvious thing to do, like: return *this * Fraction(f.den, f.num);
  Fraction operator/(Fraction f) const {
    int rNum = (f.den * num) / den;
    return Fraction(rNum, f.num); }

  // These functions support reading and writing a Fraction using streams. Note that they should
  // make use of the out and in parameters, then they would work with all stream types.
  friend ostream& operator<<(ostream& out, Fraction& f) {
    cout << f.num << " / " << f.den;
    return out; }
  // The prompts here are poor design.
  friend istream& operator>>(istream& in, Fraction& f) {
    cout << "\nEnter Numerator: ";
    cin >> f.num;
    cout << "Enter Denominator: ";
    cin >> f.den;
    cout << f.num << " / " << f.den;
    return in; }

  // This function does not do what you would expect based on the name. It returns min(num, den).
  // It should be declared const, like operator+ is since it is thread-safe.
  int ndMax() {
    return (num <= den) ? num : den; }

  // This is weird and evil. The intent is to normalize the fraction. Euclid's algorithm would
  // be the usual way.
  void reduce() {
    for (int i = 2; i <= ndMax(); i++)
      if (num % i == 0 && den % i == 0) {
        num = num / i;
        den = den / i;
        i = 1; // Evil!!! Do not modify the loop variable in the body of the loop. 
      } }

  // There are a number of other functions, not explicit here, that are implicitly generated
  // by the compiler. For example a copy constructor and assignment operator. 
};

// This is a simple test driver for the Fraction class.
int main() {
  Fraction f1(5, 6);
  Fraction f2(80, 1001);
  cout << f1 << " and " << f2 << endl;
  Fraction f3 = f1 / f2;
  f3.reduce();
  cout << f3;
  cout << endl;
  return 0; }