Advertisement
AlexDanilin

Урок 5. Раскрутка стека. Исключения в конструкторе и деструкторе

Jun 16th, 2023 (edited)
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.97 KB | None | 0 0
  1. #include <iostream>
  2. #include <numeric>
  3. #include <stdexcept>
  4. #include <string>
  5.  
  6. using namespace std;
  7.  
  8. class Rational {
  9. public:
  10.     Rational() = default;
  11.  
  12.     Rational(int value)
  13.         : numerator_(value)
  14.         , denominator_(1) {
  15.     }
  16.  
  17.     Rational(int numerator, int denominator)
  18.         : numerator_(numerator)
  19.         , denominator_(denominator) {
  20.        if (denominator_ == 0) throw domain_error("value is zero"s);
  21.         Normalize();
  22.     }
  23.  
  24.     int Numerator() const {
  25.         return numerator_;
  26.     }
  27.  
  28.     int Denominator() const {
  29.         return denominator_;
  30.     }
  31.  
  32.     Rational& operator+=(Rational right) {
  33.         numerator_ = numerator_ * right.denominator_ + right.numerator_ * denominator_;
  34.         denominator_ *= right.denominator_;
  35.         Normalize();
  36.         return *this;
  37.     }
  38.  
  39.     Rational& operator-=(Rational right) {
  40.         numerator_ = numerator_ * right.denominator_ - right.numerator_ * denominator_;
  41.         denominator_ *= right.denominator_;
  42.         Normalize();
  43.         return *this;
  44.     }
  45.  
  46.     Rational& operator*=(Rational right) {
  47.         numerator_ *= right.numerator_;
  48.         denominator_ *= right.denominator_;
  49.         Normalize();
  50.         return *this;
  51.     }
  52.  
  53.     Rational& operator/=(Rational right) {
  54.         if (right.numerator_ == 0) {
  55.             throw invalid_argument("Division by zero");
  56.         }
  57.         numerator_ *= right.denominator_;
  58.         denominator_ *= right.numerator_;
  59.         Normalize();
  60.         return *this;
  61.     }
  62.  
  63. private:
  64.     void Normalize() {
  65.         if (denominator_ < 0) {
  66.             numerator_ = -numerator_;
  67.             denominator_ = -denominator_;
  68.         }
  69.         int n = gcd(numerator_, denominator_);
  70.         numerator_ /= n;
  71.         denominator_ /= n;
  72.     }
  73.  
  74.     int numerator_ = 0;
  75.     int denominator_ = 1;
  76. };
  77.  
  78. ostream& operator<<(ostream& output, Rational rational) {
  79.     return output << rational.Numerator() << '/' << rational.Denominator();
  80. }
  81.  
  82. istream& operator>>(istream& input, Rational& rational) {
  83.     int numerator;
  84.     int denominator;
  85.     char slash;
  86.     if ((input >> numerator) && (input >> slash) && (slash == '/') && (input >> denominator)) {
  87.         rational = Rational{numerator, denominator};
  88.     }
  89.     return input;
  90. }
  91.  
  92. Rational operator+(Rational value) {
  93.     return value;
  94. }
  95.  
  96. Rational operator-(Rational value) {
  97.     return {-value.Numerator(), value.Denominator()};
  98. }
  99.  
  100. Rational operator+(Rational left, Rational right) {
  101.     return left += right;
  102. }
  103.  
  104. Rational operator-(Rational left, Rational right) {
  105.     return left -= right;
  106. }
  107.  
  108. Rational operator*(Rational left, Rational right) {
  109.     return left *= right;
  110. }
  111.  
  112. Rational operator/(Rational left, Rational right) {
  113.     return left /= right;
  114. }
  115.  
  116. bool operator==(Rational left, Rational right) {
  117.     return left.Numerator() == right.Numerator() && left.Denominator() == right.Denominator();
  118. }
  119.  
  120. bool operator!=(Rational left, Rational right) {
  121.     return !(left == right);
  122. }
  123.  
  124. bool operator<(Rational left, Rational right) {
  125.     return left.Numerator() * right.Denominator() < left.Denominator() * right.Numerator();
  126. }
  127.  
  128. bool operator>(Rational left, Rational right) {
  129.     return left.Numerator() * right.Denominator() > left.Denominator() * right.Numerator();
  130. }
  131.  
  132. bool operator>=(Rational left, Rational right) {
  133.     return !(left < right);
  134. }
  135.  
  136. bool operator<=(Rational left, Rational right) {
  137.     return !(left > right);
  138. }
  139.  
  140. // ========== для примера ========
  141.  
  142. int main() {
  143.     try {
  144.         // При попытке сконструировать дробь с нулевым знаменателем
  145.         // должно выброситься исключение domain_error
  146.         const Rational invalid_value{1, 0};
  147.         // Следующая строка не должна выполниться
  148.         cout << invalid_value << endl;
  149.     } catch (const domain_error& e) {
  150.         cout << "Ошибка: "s << e.what() << endl;
  151.     }
  152. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement