2011-09-18 77 views
3

我想寫一個矩陣類,它將能夠找到逆,伴隨等。任何次序的方陣。 構造函數初始化n階單位矩陣(傳遞給它)。矩陣類運算符重載,析構函數問題

class Matrix 
{ 
int** elements; 
int order; 

public: 
Matrix& operator=(const Matrix& second_inp) 
{ 
    if(this->order!=second_inp.order) 
     cout<<"The matrix cannot be assigned!!!\n"<<this->order<<"\n"<<second_inp.order; 

    else 
    { 
     for(int i=0;i<this->order;i++) 
      for(int j=0;j<this->order;j++) 
       this->elements[i][j] = second_inp.elements[i][j]; 

    } 

    return *this; 
} 

Matrix operator*(const Matrix& a)const 
{ 
    Matrix c(a.order); 

    for(int i=0;i<c.order;i++)      
     for(int j=0;j<c.order;j++) 
      c.elements[i][j]=0; 

    if (this->order!=a.order) 
    { 
     cout<<"The 2 Matrices cannot be multiplied!!!\n"; 
     return Matrix(); 
    } 

    else 
    { 
     for(int i=0;i<a.order;i++) 
      for(int j=0;j<a.order;j++) 
       for(int k=0;k<a.order;k++) 
        c.elements[i][j] += (this->elements[i][k])*(a.elements[k][j]); 

     return c; 
    } 
} 
}; 

~Matrix() 
{ 
    for(int i=0;i<this->order;i++) 
     delete[] *(elements+i); 
    delete[] elements; 
    elements=nullptr; 
} 

如果我使用這個類來運行下面的代碼:

Matrix exp1(2),exp2(2),exp3(2); 
exp1.get_matrix(); 
exp3=exp1*exp2; 
exp3.show_matrix(); 

我得到一個運行時錯誤,在調試時我發現,乘法(EXP1 * EXP2)後=運算符如果*運算符的結果不能訪問數據。

但是,如果我要在main()的末尾使用像這樣的手動析構函數來釋放所有分配的內存,程序將正常工作。

void destroctor() 
{ 
    for(int i=0;i<order;i++) 
    delete[] *(elements+i); 
    delete[] elements; 
} 

操作如何,我可以編輯的析構函數或重載來解決這個問題?

我使用的構造函數:

Matrix(int inp_order):order(inp_order) 
{ 
    elements=new int*[order]; 

    for(int i=0;i<order;i++) 
     *(elements+i)=new int[order]; 

    for(int i=0;i<order;i++) 
     for(int j=0;j<order;j++) 
     { 
      if (i==j) 
       *(*(elements+j)+i)=1; 
      else 
       *(*(elements+j)+i)=0; 
     } 
} 
+4

遵循三的規則。 –

+0

您的代碼中是否也包含「元素」的分配(而不僅僅是在問題中)? – eran

+0

在實際的代碼中沒有分配不會丟失。我在該問題中添加了構造函數。 – Likhit

回答

3

由於您尚未發佈您的構造函數,因此很難分辨出什麼問題。

exp3=exp1*exp2;很多事情發生了:

首先一個新的矩陣C是運營商*函數構造。然後return c;語句調用複製構造函數,然後調用析構函數。在那之後調用operator =,並在那之後重新構造臨時矩陣的析構函數。

我認爲會發生什麼是您正在使用默認複製構造函數,它不會進行深層複製。這樣,在return c時被調用的析構函數刪除了矩陣之間仍然共享的數據。

+0

它可能實際上缺少一個拷貝構造函數。 – Shautieh

+0

是的,我沒有使用複製構造函數。我認爲'operator ='的作用與複製構造函數相同,因此將直接調用。謝謝。 – Likhit

+0

@Likhit:如果你沒有提供拷貝構造函數,編譯器會爲你提供一個拷貝構造函數。在這種情況下,它只是複製指針值'elements'。當您需要始終在複製構造函數和賦值運算符重載中進行「深層複製」時,這是一個「淺層副本」。 –

0

我得到一個運行時錯誤,在調試時我發現,乘法(EXP1 * EXP2)後=運營商無法訪問數據如果*運算符的結果。

你沒告訴我們你的構造,所以沒有辦法告訴你爲什麼要得到這個錯誤。

我懷疑原因是你沒有分配需要的內存來容納你的矩陣。您將其聲明爲int**,因此您需要分配一個int*指針數組,並且對於您需要分配int數組的每個數組。

編輯
當我打字時,你爲你的構造函數發佈了代碼。

您沒有從您的超載operator*中返回值,並且您沒有複製構造函數(規則爲三)。

您是否啓用了編譯器警告?任何值得使用鹽的編譯器都會抱怨操作符重載中缺少返回語句。

+0

我很抱歉,但我在'operator *'函數中返回了臨時矩陣(c),它出現在'else'語句中。 – Likhit

+0

我沒有看到那個回報。更糟糕的是, C++有例外。使用它們。或者調用'exit()'。當你有這樣嚴重的錯誤時,不要返回一個虛假的值。更好的做法是讓這個問題成爲編譯時錯誤,但這需要使用模板。 –

0

您尚未定義複製構造函數,因此編譯器會爲您生成一個。此構造函數將被調用以將operator*(const & Matrix a)的返回值複製到結果中。

由於生成的副本構造函數只執行淺層成員副本,因此不會分配新的元素數組,因此會出錯。