2012-02-19 175 views
3

我正在嘗試爲我創建的矩陣類創建一個重載運算符。我的矩陣類將矩陣存儲在動態分配的多維數組中。我只是試圖通過將兩個矩陣相乘得到完全相同並顯示輸出來測試我的重載算子。我得到了奇怪的結果,我相信它與我的for循環中的一個條件有關。然而,我已經走過了所有的循環,並且沒有發現任何錯誤。我乘以一起的矩陣都是6x6。矩陣乘以運算符重載

我重載運營商

template <typename T> 
const matrix<T> matrix<T>::operator * (const matrix& right) const 
{ 
    matrix<T> c = right; 
    int sum_elems; 
    for(int i = 0; i < this->rows - 1; ++i) 
    { 
     for(int j = 0; j < right.cols - 1; ++j) 
     { 
      sum_elems = 0; 
      for(int k = 0; k < right.rows - 1; ++k) 
      { 
       sum_elems += this->the_matrix[i][k] * right.the_matrix[k][j]; 
      } 

      c.the_matrix[i][j] = sum_elems; 
     } 
    } 
    return c; 
}     

現在我在我的主函數調用重載的操作符:

std::cout << my_matrix; 
matrix<int> copy_matrix; 
copy_matrix = my_matrix * my_matrix; 
std::cout << copy_matrix; 

我的輸出:

The Matrix: 
0 1 0 1 1 0 
1 0 1 0 1 1 
0 1 0 1 0 1 
1 0 1 0 1 0 
1 1 0 1 0 1 
0 1 1 0 1 0 
    The Matrix: 
-1 33 139587680 18 38 75 
139587680 18 38 75 157 1 
139587712 38 1470 4365 10411 1 
139587744 75 4365 19058932 64514866 0 
139587776 157 10411 64514866 1136204102 1 
139596144 1 1 0 1 0 

正如你所看到的,似乎我正在走出我的一個陣列的界限。雖然我似乎無法找到。我很感激你的幫助。

編輯:請我矩陣類的我全面實施

表定義:

template <typename T> 
class matrix 
{ 
    public: 

     //Default Constructor 
     matrix(); 

     //Overloaded Constructor 
     matrix(std::ifstream&, const char*); 

     //Copy Constructor 
     matrix(const matrix&); 

     //Destructor 
     ~matrix(); 


     //overloaded operators 
     T* operator [] (T); 
     const matrix operator * (const matrix&) const; 
     matrix& operator = (const matrix&); 
     friend std::ostream& operator << <T> (std::ostream&, const matrix<T>&); 


    private: 
     T** the_matrix; 
     unsigned rows, cols; 

矩陣實現:

/* Template version of matrix class */ 
/*---------------------------------------------------------------------------*/ 
// Default contructor 
template <typename T> 
matrix<T>::matrix() { } 

// Overloaded contructor 
template <typename T> 
matrix<T>::matrix(std::ifstream& in, const char* file) 
{ 

    // declare the variables to be used 
    T vertices, edges, u, v; 
    std::string line; 

    // open file for reading 
    in.open(file); 

    // get number of vertices 
    in >> vertices; 


    // throw away second line 
    std::getline(in, line); 
    std::getline(in, line); 

    // get number of edges and dump them in two arrays 
    in >> edges; 
    T edge1 [edges]; 
    T edge2 [edges]; 
    int j = 0, k = 0; 
    for(int a = 0; a < edges; ++a) 
    {  
     in >> u >> v; 
     edge1[j] = u; 
     edge2[k] = v; 
     ++j; 
     ++k; 
    } 

    in.close(); 

    // Create multi-dim-dynamic array 
    rows = vertices; 
    cols = vertices; 

    the_matrix = new T*[rows]; 

    for(int b = 0; b < rows; ++b) 
    { 
     the_matrix[b] = new T [rows]; 
    } 

    // Initialize array values to zero 
    for (int c = 0; c < rows; ++c) 
    { 
     for(int d = 0; d < cols; ++d) 
     { 
      the_matrix[c][d] = 0; 
     } 
    } 

    // push the edges to the matrix 
    for(int e = 0; e < edges; ++e) 
    { 
     the_matrix[edge1[e] - 1][edge2[e] - 1] = 1; 
    } 
    for (int f = 0; f < edges; ++f) 
    { 
     the_matrix[edge2[f] - 1][edge1[f]-1] = 1; 
    } 


} 

// Copy Constructor 
template <typename T> 
matrix<T>::matrix(const matrix& left) 
{ 
    the_matrix = left.the_matrix; 
    rows = left.rows; 
    cols = left.cols; 
    spath = left.spath; 
} 

// Destructor 
template <typename T> 
matrix<T>::~matrix() 
{ 
    // Deletes the data in reverse order of allocation 
    for(int a = cols; a > 0; --a) 
    { 
     delete[ ] the_matrix[a]; 
    } 

    delete[ ] the_matrix; 
} 

// Overloaded * Operator 
template <typename T> 
const matrix<T> matrix<T>::operator * (const matrix& right) const 
{ 
    matrix<T> c = right; 
    T sum_elems; 
    for(int i = 0; i < this->rows - 1; ++i) 
    { 
     for(int j = 0; j < right.cols - 1; ++j) 
     { 
      sum_elems = 0; 
      for(int k = 0; k < right.rows - 1; ++k) 
      { 
       sum_elems += this->the_matrix[i][k] * right.the_matrix[k][j]; 
      } 

      c.the_matrix[i][j] = sum_elems; 
     } 
    } 
    return c; 
} 

// Overloaded assignment Operator 
template <typename T> 
matrix<T>& matrix<T>::operator = (const matrix& right) 
{ 
    this->the_matrix= right.the_matrix; 
    this->rows = right.rows; 
    this->cols = right.cols; 
    this->spath = right.spath; 
    return *this; 
} 

// Overloaded << operator 
template <typename T> 
std::ostream& operator << (std::ostream& output, const matrix<T>& left) 
{ 
    // Test screen output to see if correct 
    std::cout << std::setw(14) << "The Matrix:" << '\n'; 
    for(int a = 0; a < left.rows; ++a) 
    { 
     for(int b = 0; b < left.cols; ++b) 
     { 
      std::cout << ' ' << left.the_matrix[a][b] << ' '; 
     } 
     std::cout << '\n'; 
    } 
    return output; 
} 
+0

你的矩陣類是否正確地複製自己?在複製構造函數和賦值運算符中?你說你使用「動態分配的多維數組」。這是否意味着您正在使用'new'和'delete'手動管理您的內存,而不是使用矢量?如果是這樣,爲什麼? – 2012-02-19 06:54:06

+0

複製構造函數和賦值操作符完美無瑕。我沒有特別使用'vector',因爲我想了解更多關於使用operator' new'和'delete'並手動管理內存的內容,而不是總是依靠'vector'來完成幕後工作。 – 2012-02-19 06:57:47

回答

6

正如我懷疑,您的副本構造函數和賦值運算符實際上沒有正確實現。你只是簡單地將指針複製過來。這意味着當您將一個矩陣複製到另一個時,它們都共享相同的數據。當其中一個超出範圍時,調用析構函數,然後共享數據被刪除,剩下的矩陣留下懸掛指針。

修復這些函數,以便它們實際分配新陣列並複製數據。

+0

您是完全正確的。我沒有意識到我只是製作了一個指針的副本。一旦我修復了複製和賦值操作符,我的*操作符就完美了。謝謝你的幫助! – 2012-02-19 17:27:39

1
  1. i實際上從0this->rows - 2(因爲i < n-1對於i = n-1是錯誤的)。其他循環也一樣。這似乎不是矩陣乘法的正確行爲。
  2. 儘管如此,這段代碼似乎是正確的。你能爲我們提供完整的課程實施嗎?

P.S.如果T是矩陣元素的類型,那麼類型sum_elems應該是T

+0

我已按要求添加完整實施 – 2012-02-19 07:19:31