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
- Agora, vamos implementar as funções no arquivo fonte "RelationalNumber.cpp".
- A função de sobrecarga do operador de adição calculará o mínimo múltiplo comum utilizando a função gcd().
- A função de sobrecarga do operador "igual a" compara os valores dos numeradores/denominadores das frações da seguinte forma:
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
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
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.