Как умножить целочисленную константу на Fraction Object в C ++ - PullRequest
0 голосов
/ 12 ноября 2018

У меня есть класс дроби.

Мне нужно сделать 3 операции над объектом дроби, т.е.

  1. Умножить два объекта дроби.например, F1 * F2
  2. Умножить объект Fraction на целое число.НапримерF1 * 3
  3. Умножить целое число на объект Fraction.Например3 * F1.

Первые два случая могут быть достигнуты путем переопределения оператора класса дроби *.

Fraction operator*(const Fraction&);
Fraction operator*(const int&);

но как умножить целое число на объект дроби?Третий случай

Любые предложения ??

PS: я не хочу обрабатывать целое число как объект дроби, например (3/1), а затем выполнять умножение.

Ответы [ 3 ]

0 голосов
/ 12 ноября 2018

Существует три различных способа перегрузки операторов: путь функции-члена, метод функции друга и обычный метод функции.

В этом конкретном случае нам нужно перегрузить операторы в другом порядке.

friend Fraction operator*(const Fraction &a, const Fraction &b);   //F1*F2
friend Fraction operator*(const Fraction &a, int b);               //F1*3
friend Fraction operator*(int a, const Fraction &b);               //3*F1
0 голосов
/ 12 ноября 2018

Могу ли я создать футляр для функции друга на месте?

В c ++ 11 вы можете объявить и написать функцию своего друга внутри класса, что может сделать ее намного лучше:

class MyNumber
{
private:
  Clever c;
  Clever Multiply (Clever, i) { ... }
public:
  MyNumber operator * (int i)const { return Multiply(c,i)  }
  MyNumber operator * (const MyNumber &i)const { ...  }
  const MyNumber& operator *= (int i) { return c= Multiply(c, i);  }
  // introducing the inline friend (presuming multiply is commutative/symmetric here)
  friend MyNumber operator (int i, const MyNumber& j) { return j.Multiply(c,i);  }
};

Обратите внимание, что эта функция-друг все еще является глобальной функцией и имеет доступ к внутренним объектам класса, но ее реализация теперь аккуратно находится внутри определения класса.

Аккуратность этого стиля такова, что я испытываю желание использовать его, даже когда мне на самом деле не нужен доступ к грязному другу.

С этими математическими объектами перегрузки также учитывайте перегрузки замещения RValue. Реализация rvalue двоичного умножения, реализованного как множественное назначение, может показать некоторую эффективность, хотя, возможно, не так уж много, только с классом дроби с 2 значениями.

0 голосов
/ 12 ноября 2018

Вам необходимо реализовать перегрузку оператора как свободную функцию, например:

Fraction operator *(int lhs, Fraction rhs)
{
     rhs *= lhs;

     return rhs;
}

Обратите внимание, что я реализовал функцию в терминах Fraction::operator*=(int) (см. здесь , почемуэто считается хорошей практикой).Если эта функция отсутствует, вам может потребоваться передать второй параметр как const Fraction& rhs и предоставить другую реализацию.

Кроме того, обратите внимание, что идиоматический способ обработки этого сценария состоит в том, чтобы разрешить неявную конструкцию Fraction экземпляров по одному аргументу int, поэтому ваше ограничение кажется мне немного неловким.Также обратите внимание, что пользователи вашего класса Fraction могут ожидать, что все арифметические операции будут возможны (почему должно быть operator*, но не operator/?).Чтобы уменьшить объем написанного вручную кода в таких случаях, библиотека операторов поддержки boost может оказать большую помощь.

...