|
Rational.cpp (шаг 1)
#include <iostream>
using namespace std;
class Rational
{
public:
Rational(const int num, const int den)
: num_{num}
, den_{den}
{
}
int num() const
{
return num_;
}
int den() const
{
return den_;
}
private:
int num_; ///< числитель
int den_; ///< знаменатель
};
int main()
{
Rational r{1, 2};
cout << "Rational{1, 2} -> num=" << r.num() << " den=" << r.den() << endl;
}
Результат работы
Увеличим количество тестов.
Rational.cpp (шаг 2)
#include <iostream>
using namespace std;
class Rational
{
public:
Rational(const int num, const int den)
: num_{num}
, den_{den}
{
}
int num() const
{
return num_;
}
int den() const
{
return den_;
}
private:
int num_; ///< числитель, целое
int den_; ///< знаменатель, натуральное
};
int main()
{
Rational r01{1, 2};
cout << "Rational{1, 2} -> num=" << r01.num() << " den=" << r01.den() << endl;
Rational r02{-1, 2};
cout << "Rational{-1, 2} -> num=" << r02.num() << " den=" << r02.den() << endl;
Rational r03{1, -2};
cout << "Rational{-1, 2} -> num=" << r03.num() << " den=" << r03.den() << endl;
Rational r04{-1, -2};
cout << "Rational{-1, -2} -> num=" << r04.num() << " den=" << r04.den() << endl;
}
Результат работы
Добавим функции нормализации и тестирования конструктора.
rational.cpp (шаг 3)
#include <iostream>
using namespace std;
class Rational
{
public:
Rational(const int num, const int den)
: num_{num}
, den_{den}
{
normalize();
}
int num() const
{
return num_;
}
int den() const
{
return den_;
}
private:
void normalize()
{
if (0 == num_)
{
den_ = 1;
}
else if (den_ < 0)
{
num_ *= -1;
den_ *= -1;
}
}
private:
int num_; ///< числитель, целое
int den_; ///< знаменатель, натуральное
};
void testRationalConstructor(const int num, const int den)
{
Rational r{num, den};
cout << "Rational{" << num << ", " << den << "} -> num=" << r.num()
<< " den=" << r.den() << endl;
}
int main()
{
testRationalConstructor(1, 2);
testRationalConstructor(-1, 2);
testRationalConstructor(1, -2);
testRationalConstructor(-1, -2);
cout << "\nSpecial cases" << endl;
testRationalConstructor(3, 6);
testRationalConstructor(-1, 0);
}
Результат работы
Много-много шагов спустя…
Rational.cpp
#include <iostream>
#include <stdexcept>
#include <sstream>
using namespace std;
class Rational
{
public:
Rational() noexcept
: Rational{0, 1}
{
}
Rational(const int num) noexcept
: Rational{num, 1}
{
}
Rational(const int num, const int den)
: num_{num}
, den_{den}
{
if (0 == den_)
{
throw domain_error("zero denominator in Rational");
}
normalize();
}
Rational(const Rational& rhs) noexcept = default;
Rational& operator=(const Rational& rhs) = default;
Rational& operator=(Rational&& rhs) = default;
int num() const
{
return num_;
}
int den() const
{
return den_;
}
Rational operator-() const
{
return Rational{-num_, den_};
}
Rational& operator+=(const Rational& rhs)
{
num_ = num_ * rhs.den_ + den_ * rhs.num_;
den_ *= rhs.den_;
normalize();
return *this;
}
Rational& operator-=(const Rational& rhs)
{
num_ = num_ * rhs.den_ - den_ * rhs.num_;
den_ *= rhs.den_;
normalize();
return *this;
}
Rational& operator*=(const Rational& rhs)
{
num_ *= rhs.num_;
den_ *= rhs.den_;
normalize();
return *this;
}
Rational& operator/=(const Rational& rhs)
{
num_ *= rhs.den_;
den_ *= rhs.num_;
normalize();
return *this;
}
bool operator==(const Rational& rhs) const
{
return (num_ == rhs.num_) && (den_ == rhs.den_);
}
bool operator!=(const Rational& rhs) const
{
return!operator==(rhs);
}
bool operator<(const Rational& rhs) const
{
return (num_ * rhs.den_) < (rhs.num_ * den_);
}
bool operator<=(const Rational& rhs) const
{
return (num_ * rhs.den_) <= (rhs.num_ * den_);
}
bool operator>(const Rational& rhs) const
{
return!operator<=(rhs);
}
bool operator>=(const Rational& rhs) const
{
return!operator<(rhs);;
}
ostream& writeToTxt(std::ostream& ostrm) const
{
ostrm << num_ << '/' << den_;
return ostrm;
}
istream& readFromTxt(std::istream& istrm)
{
int num{0};
istrm >> num;
char sep{0};
istrm >> sep;
if ('/'!= sep)
istrm.setstate(ios_base::failbit);
int den{0};
istrm >> den;
if (istrm)
{
num_ = num;
den_ = den;
normalize();
}
return istrm;
}
private:
void normalize()
{
if (0 == num_)
{
den_ = 1;
}
else if (den_ < 0)
{
num_ *= -1;
den_ *= -1;
// TODO: упрощение до несократимой дроби
}
}
private:
int num_; ///< числитель, целое
int den_; ///< знаменатель, натуральное
};
Rational operator+(const Rational& lhs, const Rational& rhs)
{
Rational summ{lhs};
summ += rhs;
return summ;
}
Rational operator-(const Rational& lhs, const Rational& rhs)
{
Rational summ{lhs};
summ -= rhs;
return summ;
}
Rational operator*(const Rational& lhs, const Rational& rhs)
{
Rational summ{lhs};
summ *= rhs;
return summ;
}
Rational operator/(const Rational& lhs, const Rational& rhs)
{
Rational summ{lhs};
summ /= rhs;
return summ;
}
std::ostream& operator<<(std::ostream& ostrm, const Rational& r)
{
return r.writeToTxt(ostrm);
}
std::istream& operator>>(std::istream& istrm, Rational& r)
{
return r.readFromTxt(istrm);
}
void testRationalConstructor(const int num, const int den)
{
cout << "Rational{" << num << ',' << den << "} -> " << flush;
cout << Rational{num, den} << endl;
}
void testRationalOpPlus(const Rational& lhs, const Rational& rhs)
{
cout << lhs << " + " << rhs << " -> " << (lhs + rhs) << endl;
}
void testRationalOpMinus(const Rational& lhs, const Rational& rhs)
{
cout << lhs << " - " << rhs << " -> " << (lhs - rhs) << endl;
}
void testRationalOpMult(const Rational& lhs, const Rational& rhs)
{
cout << lhs << " * " << rhs << " -> " << (lhs * rhs) << endl;
}
void testRationalOpDiv(const Rational& lhs, const Rational& rhs)
{
cout << lhs << " / " << rhs << " -> " << (lhs / rhs) << endl;
}
void testRationalOpCmpEq(const Rational& lhs, const Rational& rhs)
{
cout << lhs << " == " << rhs << " -> " << boolalpha << (lhs == rhs) << endl;
}
void testRationalOpCmpNotEq(const Rational& lhs, const Rational& rhs)
{
cout << lhs << "!= " << rhs << " -> " << boolalpha << (lhs!= rhs) << endl;
}
void testRationalOpCmpLess(const Rational& lhs, const Rational& rhs)
{
cout << lhs << " < " << rhs << " -> " << boolalpha << (lhs < rhs) << endl;
}
// TODO: test for operator<= operator> operator>=
void testReadFromStream(const string& s)
{
istringstream istrm(s);
Rational r;
istrm >> r;
cout << "Read from text \"" << s << "\" -> " << r << ", stream state is "
<< boolalpha <<!!istrm << endl;
}
int main()
{
cout << "Rational{} -> " << Rational{} << endl;
Rational r02{2};
cout << "Rational{} -> " << r02 << endl;
testRationalConstructor(1, 2);
testRationalConstructor(-1, 2);
testRationalConstructor(1, -2);
testRationalConstructor(-1, -2);
try
{
testRationalConstructor(5, 0);
}
catch (domain_error& e)
{
cout << "exception caught (" << e.what() << ')' << endl;
}
Rational r03{-1, 5};
Rational r04{2, -3};
cout << "\nTest Rational operator+" << endl;
testRationalOpPlus(r03, -r03);
testRationalOpPlus(r03, r04);
cout << "\nTest Rational operator-" << endl;
testRationalOpMinus(r03, r03);
testRationalOpMinus(r03, r04);
cout << "\nTest Rational operator*" << endl;
testRationalOpMult(r03, r03);
testRationalOpMult(r03, r04);
cout << "\nTest Rational operator/" << endl;
testRationalOpDiv(r03, r03);
testRationalOpDiv(r03, r04);
cout << "\nTest Rational operator==" << endl;
testRationalOpCmpEq(r03, r03);
testRationalOpCmpEq(r03, -r03);
testRationalOpCmpEq(r03, r04);
cout << "\nTest Rational operator!=" << endl;
testRationalOpCmpNotEq(r03, r03);
testRationalOpCmpNotEq(r03, -r03);
testRationalOpCmpNotEq(r03, r04);
cout << "\nTest Rational operator<" << endl;
testRationalOpCmpLess(r03, r03);
testRationalOpCmpLess(r03, -r03);
testRationalOpCmpLess(r03, r04);
// TODO: test for operator<= operator> operator>=
cout << "\nTest Rational read from stream" << endl;
testReadFromStream("");
testReadFromStream("1");
testReadFromStream("1/2");
testReadFromStream("-4/5");
testReadFromStream("3/-5");
testReadFromStream("-5/-2");
testReadFromStream("-5.0/-2");
}
Результат работы
Дата добавления: 2015-10-24; просмотров: 95 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Quality Rate (норма качества) | | | Заключительные мысли |