矩阵重载

Matrix overloading

本文关键字:重载      更新时间:2023-10-16

我正在制作一个 2D 动态矩阵类。 我的复制构造函数和 =运算符中出现问题。请告诉我我做错了什么。这是代码:(cout用于检查。

private: 
int rows;
int coloumns;
float **ptr;
Matrix(const Matrix & M)
{     cout << "copy const called"<<endl;
    cout << "1 "<< endl;
    if(rows < 0 || column < 0)  // To check if its a garbage value or not
    {
        rows = 0, col = 0;
        ptr = NULL;
        cout << "2 "<< endl;
    }
    else if(ptr!=NULL)
    {
        cout << "3 "<< endl;
        for(int i = 0 ; i < col; i++)
        {
            delete [] ptr[i];
        }
        cout << "4 "<< endl;
        delete [] ptr;
        ptr = NULL;
        cout << "5 "<< endl;
    }
    cout << "6 "<< endl;
    *this = M;
    cout << "7 "<< endl;
}           
Matrix operator= (const Matrix &M)
{
    if(this == &M)
    {
        return *this;
    }
    if(row!=0 && columns != 0)
    {
        for(int i = 0 ; i < columns; i++)
        {
            delete [] ptr[i];
        }
        delete [] ptr;
        ptr = NULL;
    }
    rows = M.rows; col = M.columns;
        ptr = new float *[rows];
        for(int i = 0; i < rows; i++)
        {
            ptr[i] = new float [col];
        }
        for(int i = 0; i< rows ; i++)
        {
            for( int j=0 ; j< columns ;j++)
            {
                ptr[i][j] = M.ptr[i][j];
            }
        }
    return *this;
}
 int main()
 {
   Matrix M1(2,3);
   Matrix M2(M1);
   M2(0, 0) = 1;
 }

它停在复制构造函数中的 "*this = M"。此外,我想确认当我在 = 运算符中返回某些内容时,它是代替整个"*this = M",还是只是替换 M?

注意:不允许使用矢量。

你有无限的递归正在进行。 在你复制构造函数中,你有

*this = M;

这将调用您声明为 的类operator=

Matrix operator= (const Matrix &M)

您可以看到您是按值返回的。 当您按值返回时,将创建副本。 要制作该副本,我们需要调用复制构造。 这反过来又再次调用赋值运算符,该运算符调用复制构造函数,循环继续。

您的复制构造函数可以更正和简化为

Matrix(const Matrix & m) : rows(m.rows), columns(m.columns)
{
    ptr = new float*[rows];
    for (int i = 0; i < rows; i++)
        ptr[i] = new float[columns];
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < columns; j++)
            ptr[i][j] = m.ptr[i][j]
}

请注意,我不必检查新类的状态,因为我们知道它是什么,因为我们正在初始化它。 一切都是未初始化的,我们所要做的就是初始化所有内容,然后将值从一个矩阵复制到新矩阵中。

关于赋值运算符,您应该让它返回对对象的引用,而不是按值返回。 这避免了不必要的复制,并允许您将操作员与其他运算符链接在一起。

你的代码对我来说看起来很复杂。

我不明白你为什么选择float**而不是普通的float*.这对我来说看起来更好:

int rc, cc; // row count, column count
float* d; // data (rc * cc floats)

内存分配变得更简单:

d = new float[ rc * cc ];

复制也更简单:

memcpy( d, source.d, rc * cc * sizeof( *d ) );

"困难"部分是检索矩阵元素。您必须将行和列转换为索引:

index = row * column_count + column;

全班:

#include <iostream>
class matrix_type
{
  int rc, cc; // row count, column count
  float* d; // data
  void allocate( const int arc, const int acc ) // a prefix in arc and acc stands for Argument
  {
    if ( arc * acc == rc * cc )
      return; // nothing to do: already allocated
    delete[] d;
    rc = arc;
    cc = acc;
    d = new float[rc * cc];
  }
  void copy( const matrix_type& s )
  {
    allocate( s.rc, s.cc );
    memcpy( d, s.d, rc * cc * sizeof( *d ) );
  }
  int as_idx( const int ar, const int ac ) const
  {
    return ar * cc + ac;
  }
public:
  matrix_type( const int arc, const int acc ) : rc( 0 ), cc( 0 ), d( 0 )
  {
    allocate( arc, acc );
    memset( d, 0, rc * cc * sizeof( *d ) );
  }
  matrix_type()
  {
    delete[] d;
  }
  matrix_type( const matrix_type& s ) : rc( 0 ), cc( 0 ), d( 0 )
  {
    copy( s );
  }
  matrix_type& operator=(const matrix_type& s)
  {
    copy( s );
    return *this;
  }
  float& at( const int ar, const int ac )
  {
    if ( ar < rc && ac < cc )
      return d[as_idx( ar, ac )];
    else
      throw "out of range";
  }
  const float& at( const int ar, const int ac ) const
  {
    return const_cast<matrix_type*>(this)->at( ar, ac );
  }
  void print( std::ostream& os ) const
  {
    for ( int r = 0; r < rc; ++r )
    {
      for ( int c = 0; c < cc; ++c )
        os << at( r, c ) << ' ';
      os << 'n';
    }
  }
};
int main()
{
  matrix_type m1( 3, 5 );
  m1.at( 0, 0 ) = 1.f;
  m1.at( 2, 4 ) = 15.f;
  matrix_type m2( m1 );
  matrix_type m3( 0, 0 );
  m3 = m2;
  m3.print( std::cout );
  return 0;
}