2016-03-15 38 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; 
}