2016-03-15 40 views
1

我正在制作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; 
} 

它停在“*此= M”的拷贝构造函数。此外,我想确认的是,当我在=运算符返回的东西,它把整个的“*此= M”的地方,或只是取代中号

注:? 不准使用矢量

+4

“出现问题”是不是很描述。出现什么问题? –

+0

cout <<“7”将不会打印。 – chillax

+1

它在复制构造函数中的“* this = M”处停止。 另外,我想确认当我在=运算符中返回某些东西时,是否代替整个“* this = M”,或者只是替换M? – chillax

回答

2

你有无限递归事情在你拷贝构造函数你。

*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] 
} 

通知我怎么没有来检查新类的状态,因为我们知道它是什么,因为我们对其进行初始化。一切都是未初始化的,我们所要做的就是初始化所有内容,然后将这些矩阵中的值复制到新的矩阵中。

关于你的赋值操作符,你应该让它返回一个对象的引用而不是按值返回。这避免了不必要的副本,并允许您将操作员与其他操作员联系起来。

+0

我已经完成了my =操作符中的所有赋值,因此我不需要在我的拷贝构造函数中完成它。另外,我也必须记住记忆的释放(是否正确?)。那么你能告诉我怎样才能更好地写* this = M,因为我也要调用=运算符,并避免不必要的递归。 – chillax

+0

@chillax您不应该在复制构造函数中调用赋值运算符。赋值运算符的作业是将一个对象复制到已经初始化的对象中。复制构造函数的作用是将一个对象复制到正在初始化的对象中。注意'Matrix a = b;'其中'b'是一个'Matrix'不会默认初始化'a',然后调用赋值操作符,而是只调用复制构造函数。 – NathanOliver

+0

我把你的代码粘贴在我的拷贝构造函数中,但它没有给我正确的结果。 :( 我得到这个错误 终止叫做抛出“的std :: bad_alloc的” 的实例以后有什么()的std :: bad_alloc的 – chillax

0

您的代码看起来很复杂。

我不明白你为什么选择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; 
}