Classe RationalNumber. Crie uma classe Rational-

Number (frações) com as seguintes capacidades:

a) Crie um construtor que impeça um denominador 0

em uma fração, reduza ou simplifique frações que

não estejam na forma reduzida e evite denominadores

negativos.

b) Sobrecarregue os operadores de adição, subtração,

multiplicação e divisão para essa classe.

c) Sobrecarregue os operadores relacionais e de igualdade

para essa classe.

Passo 1

Vamos criar a classe RelationalNumber. A classe vai representar uma fração que tem a funcionalidade de realizar operações aritméticas com outros objetos de fração, bem como usar operadores de igualdade e relacionais.

Esses recursos serão adicionados sobrecarregando os operadores indicados pela tarefa.

Vamos declarar a classe no arquivo de cabeçalho "RelationalNumber.h" da seguinte forma (as funções serão explicadas nas próximas etapas da solução):

#ifndef H_RELATIONALNUMBER_H

#define H_RELATIONALNUMBER_H

class RelationalNumber {

public:

RelationalNumber(int = 1, int = 1);

RelationalNumber operator+(const RelationalNumber&)

const;

RelationalNumber operator-(const RelationalNumber&)

const;

RelationalNumber operator*(const RelationalNumber&)

const;

RelationalNumber operator/(const RelationalNumber&)

const;

bool operator==(const RelationalNumber&) const;

bool operator!=(const RelationalNumber&) const;

bool operator

bool operator>(const RelationalNumber&) const;

bool operator

bool operator>=(const RelationalNumber&) const;

void print() const;

private:

int gcd(int a, int b) const;

void reduce();

int numerator;

int denominator;

};

#endif

Passo 2

  1. Agora, vamos implementar as funções no arquivo fonte "RelationalNumber.cpp".
  2. Primeiramente, o cabeçalho do arquivo junto com a implementação do construtor com uma validação simples do valor do denominador e também reduz/simplifica a fração através da chamada da função que explicaremos no próximo passo.

    #include

    #include "RelationalNumber.h"

    using namespace std;

    RelationalNumber::RelationalNumber(int numerator,

    int denominator)

    {

    if (denominator == 0) {

    this->numerator = 1;

    this->denominator = 1;

    }

    else {

    this->numerator = numerator;

    this->denominator = denominator;

    reduce();

    }

    }

    ...

    Para reduzir/simplificar a fração, obtemos o máximo divisor comum do numerador e do denominador e dividimos seus valores. Além disso, multiplicaremos a fração por -1 se o denominador for negativo.

    Para calcular o máximo divisor comum de dois números, usaremos o algoritmo euclidiano que obterá o resultado recursivamente.

    Usaremos esta função para calcular a forma reduzida da fração e para calcular o mínimo múltiplo comum em funções de adição/subtração.

    int RelationalNumber::gcd(int a, int b) const {

    if (b == 0)

    return a;

    return gcd(b, a % b);

    }

    Para calcular a forma reduzida da fração, divida o numerador/denominador com o máximo divisor comum dos dois da seguinte forma:

    void RelationalNumber::reduce() {

    int divisor = gcd(numerator, denominator);

    numerator /= divisor;

    denominator /= divisor;

    if (denominator

    {

    numerator *= -1;

    denominator *= -1;

    }

    }

    Passo 3

  3. A função de sobrecarga do operador de adição calculará o mínimo múltiplo comum utilizando a função gcd().
  4. Usaremos esse valor para calcular o valor do numerador. Por fim, chamaremos a função reduce() para calcular a forma reduzida da fração.

    RelationalNumber RelationalNumber::operator+(

    const RelationalNumber &op2) const {

    int cmnDenominator = (denominator * op2.denominator)

    / gcd(denominator, op2.denominator);

    int num = numerator* (cmnDenominator / denominator)

    + op2.numerator

    * (cmnDenominator / op2.denominator);

    int den = cmnDenominator;

    RelationalNumber res(num, den);

    res.reduce();

    return res;

    }

    Da mesma forma que a função de sobrecarga do operador de adição, defina a função de sobrecarga do operador de subtração:

    RelationalNumber RelationalNumber::operator-(

    const RelationalNumber &op2) const {

    int cmnDenominator = (denominator * op2.denominator)

    / gcd(denominator, op2.denominator);

    int num = numerator* (cmnDenominator / denominator)

    - op2.numerator

    * (cmnDenominator / op2.denominator);

    int den = cmnDenominator;

    RelationalNumber res(num, den);

    res.reduce();

    return res;

    }

    Para multiplicar duas frações, basta multiplicar numeradores e denominadores separadamente da seguinte forma:

    RelationalNumber RelationalNumber::operator*(

    const RelationalNumber &op2) const {

    int num = numerator * op2.numerator;

    int den = denominator * op2.denominator;

    RelationalNumber res(num, den);

    res.reduce();

    return res;

    }

    Como a divisão de duas frações é equivalente à multiplicação de duas frações onde a segunda fração é recíproca, multiplique o numerador pelo denominador, vice-versa:

    RelationalNumber RelationalNumber::operator/(

    const RelationalNumber &op2) const {

    int num = numerator * op2.denominator;

    int den = denominator * op2.numerator;

    RelationalNumber res(num, den);

    res.reduce();

    return res;

    }

    Passo 4

  5. A função de sobrecarga do operador "igual a" compara os valores dos numeradores/denominadores das frações da seguinte forma:

bool RelationalNumber::operator==(

const RelationalNumber &op2) const {

return numerator == op2.numerator

&& denominator == op2.denominator;

}

Use a função de sobrecarga do operador "igual a" para criar a função de sobrecarga do operador "diferente de":

bool RelationalNumber::operator!=(

const RelationalNumber &op2) const {

return !(*this == op2);

}

Para ver se a fração é menor que a outra, vamos calcular o valor decimal das frações e compará-las:

bool RelationalNumber::operator

const RelationalNumber &op2) const {

return (double)numerator / denominator

(double)op2.numerator / op2.denominator;

}

Implemente as funções de sobrecarga de operador relacional restantes usando as definidas anteriormente da seguinte forma:

bool RelationalNumber::operator>(

const RelationalNumber &op2) const {

return !(*this

}

bool RelationalNumber::operator

const RelationalNumber &op2) const {

return *this == op2 || *this

}

bool RelationalNumber::operator>=(

const RelationalNumber &op2) const {

return *this == op2 || *this > op2;

}

Para fins de demonstração da classe, criaremos a função print():

void RelationalNumber::print() const {

cout

}

O arquivo principal para fins de demonstração:

#include

#include "RelationalNumber.h"

using namespace std;

int main()

{

RelationalNumber f1(2, 4);

RelationalNumber f2(6, 3);

f1.print();

f2.print();

(f1 * f2).print();

(f1 / f2).print();

if (f1

cout

}

Resposta

Ver o desenvolvimento.