Тема: допоможіть виправити помилки у програмі
Створити клас Frac (дробові числа) з перевантаженими операціями + - * /, а також з можливістю приведення типу Frac-> double. Повинні бути реалізовані також ToString (), Equals (), ==,! =. Обчислити значення полінома в точці. Всі коефіцієнти і x повинні мати тип Frac. Порівняти продуктивність в разі реалізації Frac як класу і як структури
Код
#include <iostream>
#include <stdexcept>
#include <sstream>
struct IComparable {
virtual bool Equal(const IComparable&) const = 0;
};
template <typename T>
T gcd (const T& m, const T& n) {
return n == 0 ? m : gcd (n, m % n);
}
class Frac : public IComparable {
int p, q;
void reduce () {
int d = gcd (p,q);
p /= d;
q /= d;
if (q < 0) {
q = -q;
p = -p;
}
}
public:
Frac (int p=0,int q=1) : p(p), q(q) {
if (q == 0) throw std::invalid_argument("Делитель равен 0");
reduce ();
}
std::string ToString() const {
std::stringstream s;
if (q!=1) s << '(';
if (p>q && p%q)
s << p/q << ' ' << p%q;
else
s << p;
if (q!=1) s << '/' << q << ')';
return s.str();
}
bool operator==(const Frac& other) const {
return p == other.p && q == other.q;
}
bool operator!=(const Frac& other) const {
return !(*this == other);
}
bool Equal(const IComparable& other) const {
const Frac* o = dynamic_cast<const Frac*>(&other);
return o ? *o == *this : false;
}
explicit operator double() const {
return double(p)/q;
}
Frac operator ~() const {
return Frac(q,p);
}
Frac operator -() const {
return Frac(-p,q);
}
Frac& operator +=(const Frac& other) {
p = p*other.q + other.p*q;
q *= other.q;
reduce();
return *this;
}
Frac& operator -=(const Frac& other) {
return *this += -other;
}
Frac& operator *=(const Frac& other) {
p *= other.p;
q *= other.q;
reduce();
return *this;
}
Frac& operator /=(const Frac& other) {
return *this *= ~other;
}
};
Frac operator+(const Frac& lhs, const Frac& rhs) { return Frac (lhs) += rhs; }
Frac operator-(const Frac& lhs, const Frac& rhs) { return Frac (lhs) -= rhs; }
Frac operator*(const Frac& lhs, const Frac& rhs) { return Frac (lhs) *= rhs; }
Frac operator/(const Frac& lhs, const Frac& rhs) { return Frac (lhs) /= rhs; }
Frac polynomial (Frac coef[], size_t n, const Frac& x) {
if (n==0) return 0;
Frac result=coef[n-1];
for (size_t i=n-2; i < n; --i) {
result *= x;
result += coef[i];
}
return result;
}
std::string PolynomialToString (Frac poly[], size_t n) {
std::stringstream s;
for (size_t i=n-1; i < n; --i) {
if (poly[i] != 0) {
if (poly[i] != 1 || i == 0) {
s << poly[i].ToString();
if (i > 0)
s << '*';
}
if (i > 0) {
s << 'x';
if (i > 1)
s << "^" << i;
s << "+";
}
}
}
return s.str();
}
int main () {
Frac poly[] = { Frac(3,2), Frac(1,-3), 0, -Frac (2,7) };
const size_t n = sizeof poly / sizeof poly[0];
Frac x(2,8);
Frac result = polynomial (poly, n, x);
std::cout << PolynomialToString (poly, n) << '=' << result.ToString();
std::cout << '=' << static_cast<double>(result);
std::cout << " при x=" << x.ToString();
std::cout << "\n" << (Frac(2,3)/Frac(2,3)).ToString();
}
Але при компіляції виникають помилки
d:\c-+\struct_frac\class_frac\class.cpp(57): error C2071Frac::operator double: недопустимый класс хранения
1>d:\c-+\struct_frac\class_frac\class.cpp(100): error C2666: Frac::operator !=: для 2 перегрузок есть подобные преобразования
1> d:\c-+\struct_frac\class_frac\class.cpp(48): может быть "bool Frac::operator !=(const Frac &) const"
1> или "встроенный оператор C++!=(double, int)"
1> при попытке сопоставить список аргументов "(Frac, int)"
1>d:\c-+\struct_frac\class_frac\class.cpp(101): error C2666: Frac::operator !=: для 2 перегрузок есть подобные преобразования
1> d:\c-+\struct_frac\class_frac\class.cpp(48): может быть "bool Frac::operator !=(const Frac &) const"
1> или "встроенный оператор C++!=(double, int)"
1> при попытке сопоставить список аргументов "(Frac, int)"