A
A
Alyona_pr2021-11-06 19:06:35
OOP
Alyona_pr, 2021-11-06 19:06:35

How to correctly implement the rational number template class in C++?

Good afternoon, task: to write a template class of rational numbers with an overload of fraction reduction.
For the option when the numerator and denominator are initially everywhere of type int, everything works.
The problem is to make this class a template one.
Now it gives the following errors:

error LNK2019: ссылка на неразрешенный внешний символ "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl operator>>(class std::basic_istream<char,struct std::char_traits<char> > &,class rat<int> &)" ([email protected][email protected][email protected]@[email protected]@@[email protected]@[email protected][email protected]@@@Z) в функции _main
error LNK2019: ссылка на неразрешенный внешний символ "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class rat<int> const &)" ([email protected][email protected][email protected]@[email protected]@@[email protected]@[email protected][email protected]@@@Z) в функции _main
 fatal error LNK1120: неразрешенных внешних элементов: 2


The code is written in Visual Studio:
#include <iostream>
using namespace std;

template <class T> 
class rat{
  T ch, zn;
public:
  friend istream& operator>>(istream& stream_in, rat<T> &rvalue); 
  friend ostream& operator<<(ostream& stream_out,const rat<T> &rvalue); 
  T nod(T, T);  // наибольший общий делитель 
  T abs(T); // модуль числа 
  rat(int = 0, int = 1); 
  void norm(); // для сокращения дроби  
};

template <class T> T rat <T>::abs(T x) {
  if (x < 0)
    return (-1)*x;
  return x;
}
template <class T> T rat <T>::nod(T x, T y) { 
  if (x == 0 || y == 0)
    return 1;
  while (x != y)
    if (x > y)
      x = x - y;
    else
      y = y - x;
  return x;
}
template <class T> rat <T>::rat(int x, int y) { 
  if (!y || !x) {
    ch = 0;
    zn = 1;
  }
  ch = x;
  zn = y;
  this->norm();
}
template <class T> void rat <T>::norm() {  
  int sign = 1;
  if (ch*zn < 0)
    sign = (-1);
  ch = abs(ch);
  zn = abs(zn);
  T b = nod(ch, zn);
  if (ch == 0 || zn == 0)
    zn = 1; 
  if (b == 1)
    return;
  ch = (ch / b)*sign;
  zn = zn / b;
}

template <class T> istream& operator>>(istream& stream_in, rat<T> &rvalue) {
  cout << "Enter rational value (a/b): ";
  stream_in >> rvalue.ch;
  stream_in.ignore();
  stream_in >> rvalue.zn;
  cout << endl;
  return stream_in;
};

template <class T> ostream& operator<<(ostream& stream_out,const rat<T> &rvalue) {
  stream_out << "Rational number: " << rvalue.ch << "/" << rvalue.zn << endl;
  return stream_out;
}

int main() {
  rat <int> a;
  cin >> a;  
  cout <<  a  << endl;

  return 0;
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
U
User700, 2021-11-06
@Alyona_pr

Here:

template <class T> istream& operator>>(istream& stream_in, rat<T> &rvalue) {
  cout << "Enter rational value (a/b): ";
  stream_in >> rvalue.ch;
  stream_in.ignore();
  stream_in >> rvalue.zn;
  cout << endl;
  return stream_in;
};

There should be no binding to cout. Work only with the stream_in stream, because data is not necessarily read from the console, and such an operator must also read from a file. The input prompt should be done "in main", or implement a prompt input method that takes two threads. You don't need to do a line break after input either.
Main problem:
Not quite correct solution, see comments:
public:
  template <class T1> 
  friend istream& operator>>(istream& stream_in, rat<T1> &rvalue); 
  template <class T1>
  friend ostream& operator<<(ostream& stream_out, const rat<T1> &rvalue);

UPD:
Correct
template <class T> class rat;
template <class T> istream& operator>>(istream& stream_in, rat<T> &rvalue);
template <class T> ostream& operator<<(ostream& stream_out,const rat<T> &rvalue);

template <class T> 
class rat{
  T ch, zn;
public:
  friend istream& operator>> <T> (istream& stream_in, rat &rvalue); 
  friend ostream& operator<< <T> (ostream& stream_out, const rat &rvalue);
  //......
};

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question