简体   繁体   English

麻烦重载operator >> for matrix class

[英]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 我试图通过处理重载>>来学习运算符重载,用于矩阵类,通过调用sth来启用矩阵的基于键盘的输入

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; 我通过模仿现有的重载>>实现上面的部分,已经证明在矩阵输出部分工作得很好,比如cout << A; where A is a matrix 其中A是矩阵

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. 我相信你的operator >>的问题在于你正在使用已经碰巧在Matrix中的任何维度,而不是试图从你找到的输入中恢复维度。

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. 我认为你最好的选择是让operator << implementation在矩阵中加上维度信息(例如行数和列数),然后在该信息中读取operator >>函数。 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. 作为一个FYI,您可能不希望在编写流插入运算符时使用endl来分隔行。 In addition to writing a newline, endl flushes the buffer. 除了编写换行符之外, endl还会刷新缓冲区。 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 希望这可以帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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