Оператор перегрузки проблем >> для класса матрицы - PullRequest
3 голосов
/ 21 марта 2011

Я пытаюсь научиться перегружать операторы, работая над перегрузкой >> для класса матрицы, чтобы включить основанный на клавиатуре ввод для матрицы, вызывая sth, например

Matrix M1;
cin >> M1;

Часть перегрузки оператора приведена в следующем

istream &operator>>(istream &in, Matrix &m) 
{
    for (int i = 0; i < m.dx; ++i)    {
        for (int j = 0; j < m.dy; ++j)
            in >> m.p[i][j];
    }
    return in;
}

Оказывается, моя реализация была неверной. Можете ли вы дать мне знать, почему эта реализация неверна?

Я реализовал вышеупомянутую часть, имитируя существующую реализацию перегрузки >>, которая, как было доказано, прекрасно работает в матричной выходной части, например, cout << A; где A - матрица </p>

ostream &operator<<(ostream &out, const Matrix &m) 
{
    for (int i = 0; i < m.dx; ++i)    {
        for (int j = 0; j < m.dy; ++j)
            out << m.p[i][j] << "  ";
        out << endl;
    }
    return out;
}

Ответы [ 3 ]

1 голос
/ 21 марта 2011

Я считаю, что проблема с вашим operator >> заключается в том, что вы используете те измерения, которые уже есть в Matrix, а не пытаетесь восстановить измерения из найденного вами ввода.

Я думаю, что лучше всего было бы сделать так, чтобы реализация operator << предшествовала матрице с информацией о размерах (например, числом строк и столбцов), а затем читала в этой информации функцию operator >>.Например:

ostream &operator<<(ostream &out, const Matrix &m) 
{
   out << m.dx << ' ' << out.dy << '\n';
   for (int i = 0; i < m.dx; ++i)    {
      for (int j = 0; j < m.dy; ++j)
        out << m.p[i][j] << "  ";
      out << endl;
   }
   return out;
 }

Имея это в виду, вы можете написать свой оператор извлечения потока как

istream &operator>>(istream &in, Matrix &m) 
{
   in >> m.dx >> m.dy;

   /* Some sort of logic to ensure that you've allocated an array large enough to
    * hold all the elements ...
    */

   for (int i = 0; i < m.dx; ++i)    {
       for (int j = 0; j < m.dy; ++j)
           in >> m.p[i][j];
   }
   return in;
}

Это может быть не самый эстетически приятный оператор ввода и вывода, но они должныВыполни работу.

Если вы хотите сделать эти операторы немного более классифицированными, рассмотрите возможность вывода элементов матрицы с использованием какого-либо специального символа для разделения строк и столбцов.Например, вы можете попытаться вывести матрицу

0 1 2
3 4 5
6 7 8

как

[[0 1 2][3 4 5][6 7 8]]

При такой настройке информация о размере матрицы неявно указывается в том, как работает группировка скобок.Опять же, это может усложнить чтение входных данных, поскольку вы не знаете заранее, насколько велика матрица.Но в целом вам будет проще всего.

Как к сведению, вы, вероятно, не захотите использовать endl для разграничения строк при написании оператора вставки потока.В дополнение к написанию новой строки, endl очищает буфер.Если ваш поток подключен к сетевому соединению, вы, возможно, не захотите продолжать очищать буфер всякий раз, когда у вас будет новая строка матрицы, так как это может привести к тому, что большая часть данных будет отправляться пакетными (медленными), а не группировать их.все вместе сразу (быстро).

Надеюсь, это поможет!

0 голосов
/ 17 сентября 2013
#include<iostream>

using namespace std;

class Array /*overload of subscript operator of 1D array*/
{
     private: int *p;
     public:
          int length;
          Array(int size = 0): length(size)
          {
                p=new int(length);
          }
          int& operator [](const int k)
          {
               return p[k];
          }
};
class Matrix
{
      private: Array *p;
      public: 
            int r,c;
            Matrix(int i=0, int j=0):r(i), c(j)
            {
                 p= new Array[r];
            }
            Array& operator [](const int& i)
            {
                 return p[i];
            }
            friend istream& operator >> (istream& in, Matrix& m);
          /*friend ostream& operator << (ostream& out, Matrix& m);*/
};
istream& operator >> (istream& in, Matrix& m)
{
     for(int i=0 ; i < m.r ; i++)
     {
         for(int j=0 ; j < m.c ; j++)
               in >> m[i][j];
     }
}
/*ostream& operator << (ostream& out, Matrix& m)
{
     for(int i=0 ; i < m.r ; i++)
     {
         for(int j=0 ; j < m.c ; j++)
               out << m[i][j] << " ";
         out << endl;
     }
}*/

/*Driver program*/
int main()
{
    Matrix M1(3,3); /*for checking purpose*/
    cin >> M1;
  /*cout << "\n" << M1;*/
}
0 голосов
/ 21 марта 2011

Я не думаю, что ваш код особенно неправильный.При нажатии я бы предложил проверить состояние потока в цикле.Для вашей информации, следующий код работал, когда я тестировал:

struct Matrix {
    static int const dx = 2, dy = 2;
    int p[ dx ][ dy ];
};

istream &operator>>(istream &in, Matrix &m) 
{
   for (int i = 0; i < m.dx; ++i)    {
       for (int j = 0; j < m.dy; ++j)
           if ( ! (in >> m.p[i][j]) ) return in;
 }
 return in;
}

int main() {
    Matrix M1;
    cin >> M1;
    cout << M1;
}

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...