简体   繁体   中英

Trouble overloading operator >> for a matrix class

I am trying to learn operator overloading by working on overloading >> for a matrix class to enable the key-board based input for a matrix by calling sth such as

Matrix M1;
cin >> M1;

The operator overloading part is given in the following

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;
}

It turns work that my implementation was not correct at all. Can you let me know why this implementation is wrong?

I implemented the above part by imitating an existing implementation of overloading >>, which has been proven to work fine in the matrix output part, like cout<< A; where A is a matrix

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;
}

I believe that the problem with your operator >> is that you're using whatever dimensions already happen to be in the Matrix rather than trying to recover the dimensions from the input that you find.

I think that your best bet would be to have the operator << implementation preface the matrix with dimension information (such as the number of rows and columns) and then have the operator >> function read in that information. For example:

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;
 }

With this in hand, you can write your stream extraction operator as

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;
}

This may not be the most aesthetically pleasing input and output operators, but they should get the job done.

If you want to make these operators a bit classier, consider outputting the elements of the matrix using some special character to delimit rows and columns. For example, you might try outputting the matrix

0 1 2
3 4 5
6 7 8

as

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

With this setup, the size information about the matrix is implicit in how the bracket grouping works. Then again, this may make it a bit trickier to read the input, since you wouldn't know in advance how large the matrix is. But go with what's easiest for yourself overall.

As an FYI, you probably don't want to use endl to delimit lines when writing a stream insertion operator. In addition to writing a newline, endl flushes the buffer. If your stream is hooked up to a network connection, you may not want to keep flushing the buffer whenever you have a new line of the matrix, since that could result in a lot of data getting sent in bursts (slow) rather than grouping it all together at once (fast).

Hope this helps!

#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;*/
}

I don't think your code is wrong particularly. If pressed I would suggest checking the stream condition in the loop. For your information, the following code worked when I tested:

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;
}

Hope this helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM