2015-06-06 90 views
0

我在運行此代碼時遇到問題。它應該是一個帶有構造函數,析構函數,複製構造函數和運算符重載的模板化二維數組。C++操作符重載<<錯誤。 SafeMatrix 2D陣列

我的主要問題是在導致錯誤的ostream& operator<<(ostream& os, SafeMatrix<class T> s) overloader。主要,當我cout<<b[0][0],它打印罰款,但是當我在ostream& operator<<(ostream& os, SafeMatrix<class T> s) overloader中,我得到錯誤。我正在試圖打印像cout << b這樣的對象,就像你在main中看到的一樣。

可能存在很多編碼錯誤。對不起,我是模板和重載的新手。我一直在閱讀和閱讀,無法找到與我的項目相關的任何內容。

#include <iostream> 
#include <cstdlib> 
#include <cassert> 

using namespace std; 
template <class T> class SafeMatrix{ 
private: 
    int row_low, row_high, col_low, col_high; 
    T** p; 
public: 

    // default constructor 
    // allows for writing things like SafeMatrix a; 
    SafeMatrix() : row_low(0), row_high(-1) 
     , col_low(0), col_high(-1), p(nullptr){ } 


    // 1 parameter constructor 
    // SafeMatrix (10); 
    SafeMatrix(int dim){ 
     if (dim <= 0){ 
      cout << "constructor error in bounds definition" << endl; 
      exit(1); 
     } 
     row_low = 0; row_high = dim - 1; 
     col_low = 0; col_high = dim - 1; 
     p = new T*[dim]; 
     for (int i = 0; i < dim; i++) 
      p[i] = new T[dim]; 
    } 


    // 2 parameter constructor lets us write 
    // SafeMatrix (10,20); 
    SafeMatrix(int row, int col){ 
     if (row <= 0 || col<=0){ 
      cout << "constructor error in bounds definition" << endl; 
      exit(1); 
     } 
     row_low = 0; row_high = row - 1; 
     col_low = 0; col_high = col - 1; 
     p = new T*[row]; 
     for (int i = 0; i < row; i++) 
      p[i] = new T[col]; 
    } 


    // 2 parameter constructor lets us write 
    // SafeMatrix (10,20); 
    SafeMatrix(int row_low, int row_high, int col_low, int col_high){ 
     if ((row_high - row_low + 1) <= 0 || (col_high - col_low + 1) <= 0){ 
      cout << "constructor error in bounds definition" << endl; 
      exit(1); 
     } 
     this.row_low = row_low; this.row_high = row_high - 1; 
     this.col_low = col_low; this.col_high = col_high - 1; 
     p = new T*[(col_high - col_low) + 1]; 
     for (int i = 0; i <= row_high-row_low; i++) 
      p[i] = new T[(col_high - col_low) + 1]; 
    } 


    // copy constructor for pass by value and 
    // initialization 
    SafeMatrix(const SafeMatrix &s){ 
     int row = (s.row_high - s.row_low) + 1, 
      col = (s.col_high - s.col_low) + 1; 
     p = new T*[row]; 
     for (int i = 0; i < row; i++) 
      p[i] = new T[col]; 
     for (int i = 0; i < row; i++) 
      for (int j = 0; j < col;j++) 
       p[i][j] = s.p[i][j]; 
     row_low = s.row_low; row_high = s.row_high; 
     col_low = s.col_low; col_high = s.col_high; 
    } 


    // destructor 
    ~SafeMatrix(){ 
     for (int i = 0; i < (row_high - row_low) + 1; i++) 
      delete[] p[i]; 
     delete[] p; 
    } 

    friend class Brackets; 

    //overloaded [] lets us write 
    //SafeMatrix x(10,20); x[15]= 100; 
    class Brackets { 
    private: 
     T* p1; 
    public: 
     Brackets(T* p2) : p1(p2) { } 

     T& operator[](int i) { 
      /*if (i<col_low || i>col_high) { 
       cout << "index " << i << " out of range" << endl; 
       exit(1); 
      }*/ 
      return p1[i]; 
     } 
    }; 

    Brackets operator[](int i) { 
     if (i<row_low || i>row_high) { 
      cout << "index " << i << " out of range" << endl; 
      system("pause"); 
      exit(1); 
     } 
     return Brackets(p[i]); 
    } 


    // overloaded assignment lets us assign 
    // one SafeMatrix to another 
    SafeMatrix& operator=(const SafeMatrix & s){ 
     if (this != &s){ 
      delete[] p; 
      int row = (s.row_high - s.row_low) + 1, 
       col = (s.col_high - s.col_low) + 1; 
      p = new T*[row]; 
      for (int i = 0; i < col; i++) 
       p[i] = new T[col]; 
      for (int i = 0; i < row; i++) 
       for (int j = 0; j < col; j++) 
        p[i][j] = s.p[i][j]; 
      this.row_low = s.row_low; this.row_high = s.row_high; 
      this.col_low = s.col_low; this.col_high = s.col_high; 
     } 
     return *this; 
    } 


    // overloads << so we can directly print SafeMatrix 
    friend ostream& operator<<(ostream& os, const SafeMatrix<T> s); 

}; 

ostream& operator<<(ostream& os, SafeMatrix<class T> s){ 
    int row = (s.row_high - s.row_low) + 1, 
     col = (s.col_high - s.col_low) + 1; 
    for (int i = 0; i < row; i++){ 
     for (int j = 0; j < col; j++){ 
     cout << *((s.p+i)+j) << " "; 
     } 
     cout << endl; 
    } 
    return os; 
}; 

int main(){ 

    SafeMatrix<int> b(3, 5); 
    b[2][0] = 3; 
    cout << b[2][0] <<endl; 
    int counter = 0; 
    for (int i = 0; i<3; i++) 
     for (int j = 0; j < 5; j++) 
      b[i][j] = ++counter; 
    cout << "printing b the first time" <<endl; 
    cout << b << endl; 
    cout << "printing using []" << endl; 
    for (int i = 0; i < 3; i++){ 
     for (int j = 0; j < 5; j++){ 
      cout << b[i][j] << " "; 
     } 
     cout << endl; 
    } 
} 

我得到的錯誤是有點瘋狂,但在這裏,他們是:

error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class SafeMatrix<int>)" ([email protected][email protected][email protected]@[email protected]@@[email protected]@[email protected][email protected]@@@Z) referenced in function _main D:\OneDrive\VS\SafeMatrix\matrix.obj SafeMatrix 

error LNK1120: 1 unresolved externals D:\OneDrive\VS\SafeMatrix\Debug\SafeMatrix.exe 1 1 SafeMatrix 

和這樣的警告:

Warning 1 warning C4150: deletion of pointer to incomplete type 'T'; no destructor called d:\onedrive\vs\safematrix\matrix.cpp 82 1 SafeMatrix 

不知道這些是什麼意思。

+0

什麼是你看到的錯誤? – user35443

+0

@ user35443我添加了錯誤。預先感謝您的任何幫助。 – fanterrific

回答

0

重載運算符聲明必須爲自己的模板聲明:

template <class U> 
ostream& operator<<(ostream& os, const SafeMatrix<U> s); 

此外,類內部的友元聲明必須使用一個新的類型參數名稱,如:

template <class U> 
friend ostream& operator<<(ostream& os, const SafeMatrix<U> s); 

它可能不是重用T型參數。重載運算符的類型參數是不同的。

+0

TY!奇蹟般有效!不能相信它是如此之小。 – fanterrific

0

我想你簡單的忘了添加一個模板來超載。我沒有檢查的其餘部分:

#include <iostream> 
#include <cstdlib> 
#include <cassert> 

using namespace std; 

template <typename T> class SafeMatrix{ 
private: 
    int row_low, row_high, col_low, col_high; 
    T** p; 
public: 

    // default constructor 
    // allows for writing things like SafeMatrix a; 
    SafeMatrix() : row_low(0), row_high(-1) 
     , col_low(0), col_high(-1), p(nullptr){ } 


    // 1 parameter constructor 
    // SafeMatrix (10); 
    SafeMatrix(int dim){ 
     if (dim <= 0){ 
      cout << "constructor error in bounds definition" << endl; 
      exit(1); 
     } 
     row_low = 0; row_high = dim - 1; 
     col_low = 0; col_high = dim - 1; 
     p = new T*[dim]; 
     for (int i = 0; i < dim; i++) 
      p[i] = new T[dim]; 
    } 


    // 2 parameter constructor lets us write 
    // SafeMatrix (10,20); 
    SafeMatrix(int row, int col){ 
     if (row <= 0 || col <= 0){ 
      cout << "constructor error in bounds definition" << endl; 
      exit(1); 
     } 
     row_low = 0; row_high = row - 1; 
     col_low = 0; col_high = col - 1; 
     p = new T*[row]; 
     for (int i = 0; i < row; i++) 
      p[i] = new T[col]; 
    } 


    // 2 parameter constructor lets us write 
    // SafeMatrix (10,20); 
    SafeMatrix(int row_low, int row_high, int col_low, int col_high){ 
     if ((row_high - row_low + 1) <= 0 || (col_high - col_low + 1) <= 0){ 
      cout << "constructor error in bounds definition" << endl; 
      exit(1); 
     } 
     this.row_low = row_low; this.row_high = row_high - 1; 
     this.col_low = col_low; this.col_high = col_high - 1; 
     p = new T*[(col_high - col_low) + 1]; 
     for (int i = 0; i <= row_high - row_low; i++) 
      p[i] = new T[(col_high - col_low) + 1]; 
    } 


    // copy constructor for pass by value and 
    // initialization 
    SafeMatrix(const SafeMatrix &s){ 
     int row = (s.row_high - s.row_low) + 1, 
      col = (s.col_high - s.col_low) + 1; 
     p = new T*[row]; 
     for (int i = 0; i < row; i++) 
      p[i] = new T[col]; 
     for (int i = 0; i < row; i++) 
     for (int j = 0; j < col; j++) 
      p[i][j] = s.p[i][j]; 
     row_low = s.row_low; row_high = s.row_high; 
     col_low = s.col_low; col_high = s.col_high; 
    } 


    // destructor 
    ~SafeMatrix(){ 
     for (int i = 0; i < (row_high - row_low) + 1; i++) 
      delete[] p[i]; 
     delete[] p; 
    } 

    friend class Brackets; 

    //overloaded [] lets us write 
    //SafeMatrix x(10,20); x[15]= 100; 
    class Brackets { 
    private: 
     T* p1; 
    public: 
     Brackets(T* p2) : p1(p2) { } 

     T& operator[](int i) { 
      /*if (i<col_low || i>col_high) { 
      cout << "index " << i << " out of range" << endl; 
      exit(1); 
      }*/ 
      return p1[i]; 
     } 
    }; 

    Brackets operator[](int i) { 
     if (i<row_low || i>row_high) { 
      cout << "index " << i << " out of range" << endl; 
      system("pause"); 
      exit(1); 
     } 
     return Brackets(p[i]); 
    } 


    // overloaded assignment lets us assign 
    // one SafeMatrix to another 
    SafeMatrix& operator=(const SafeMatrix & s){ 
     if (this != &s){ 
      delete[] p; 
      int row = (s.row_high - s.row_low) + 1, 
       col = (s.col_high - s.col_low) + 1; 
      p = new T*[row]; 
      for (int i = 0; i < col; i++) 
       p[i] = new T[col]; 
      for (int i = 0; i < row; i++) 
      for (int j = 0; j < col; j++) 
       p[i][j] = s.p[i][j]; 
      this.row_low = s.row_low; this.row_high = s.row_high; 
      this.col_low = s.col_low; this.col_high = s.col_high; 
     } 
     return *this; 
    } 


    // overloads << so we can directly print SafeMatrix 
    template <typename T> friend ostream& operator<<(ostream& os, const SafeMatrix<T> s); 

}; 

template <typename T> 
ostream& operator<< (ostream& os, const SafeMatrix<T> s) { 
    int row = (s.row_high - s.row_low) + 1, 
     col = (s.col_high - s.col_low) + 1; 
    for (int i = 0; i < row; i++){ 
     for (int j = 0; j < col; j++){ 
      os << *((s.p + i) + j) << " "; 
     } 
     os << endl; 
    } 
    return os; 
} 

int main(){ 
    SafeMatrix<int> a(10), b(3, 5); 
    b[2][0] = 3; 
    cout << b << endl; 

    system("PAUSE"); 
    return 0; 
} 

該代碼可以使用十六進制打印...