2013-03-13 63 views
-1

我需要一些幫助來爲我的類中的動態數組實現一個拷貝構造函數和一個operator = =。 林不允許在這一點上拷貝構造函數和operator =爲一個類中的動態數組

這裏使用向量是MYE代碼: 類:

class Matrix{ 
    private: 
     int rows; 
     int columns; 
     double* matrix; 
    public: 
     Matrix(); 
     explicit Matrix(int N); 
     Matrix(int M, int N); 
     void setValue(int M, int N, double value); 
     double getValue(int M, int N); 
     bool isValid() const; 
     int getRows(); 
     int getColumns(); 
     ~Matrix(); 
     friend ostream& operator<<(ostream &out, Matrix&matrix1);  
}; 

而且我的代碼:

Matrix::Matrix(){ 
    matrix = NULL; 
} 

Matrix::Matrix(int N){ 
    matrix = new double[N * N]; 
    rows = N; 
    columns = N; 

    for(int i = 0; i < N; i++){ 
     for(int j = 0; j < N; j++){ 
      if(i==j) 
       matrix[i * N + j] = 1; 
      else 
       matrix[i * N + j] = 0; 
     } 
    } 
} 

Matrix::Matrix(int M, int N){ 
    matrix = new double[M * N]; 
    rows = M; 
    columns = N; 

    for(int i = 0; i < M; i++){ 
     for(int j = 0; j < N; j++) 
      matrix[i * N + j] = 0; 
    } 
} 

Matrix::~Matrix(){ 
    delete [] matrix; 
} 

void Matrix::setValue(int M, int N, double value){ 
    matrix[M * columns + N] = value; 
} 

double Matrix::getValue(int M, int N){ 
    return matrix[M * columns + N]; 
} 

bool Matrix::isValid() const{ 
    if(matrix==NULL) 
     return false; 
    else 
     return true; 
} 

int Matrix::getRows(){ 
    return rows; 
} 

int Matrix::getColumns(){ 
    return columns; 
} 

ostream& operator<<(ostream &out, Matrix&matrix1){ 
    if(matrix1.isValid()) 
     for(int i = 0; i < matrix1.getRows(); i++){ 
      for(int j = 0; j < matrix1.getColumns(); j++) 
       out << matrix1.getValue(i,j) << "\t"; 
      out << endl; 
     } 
    else 
     out << "Matrisen er ikke gyldig."; //the matrix is not valid 
    return out; 
} 

會是這樣的工作?

Matrix &operator=(const Matrix &m) {*(this->matrix) = *(m.matrix);} 
Matrix(const Matrix &rhs) : matrix(0) { 
     this->matrix = new double(); 
     *(this->matrix) = *(rhs.matrix); 
    } 

我也要重載運算符+ =和+。 我試圖執行此爲:

const Matrix operator+=(Matrix matrix1, Matrix matrix2){ 
     if(!matrix1.isValid() || !matrix2.isValid()){ 
      cout << "En av matrisene er ugyldig"; //one of the matrices are invalid 
      return Matrix::Matrix(); //returning a NULL matrix 
     } 
     else{ 
      if(matrix1.getColumns()==matrix2.getColumns() && matrix1.getRows()==matrix2.getRows()){ 
       Matrix temp(matrix1.getRows(), matrix1.getColumns()); 
       for(int i = 0; i < matrix1.getRows(); i++){ 
        for(int j = 0; j < matrix1.getColumns(); j++) 
         temp.setValue(i,j,(matrix1.getValue(i,j) + matrix2.getValue(i,j))); 
       } 
       return temp; 
      } 
      else{ 
       cout << "Matrisene har ikke samme dimensjon"; //the matrices does not have the same dimensions 
       return Matrix::Matrix(); 
      } 
     } 
    } 
    const Matrix operator+(Matrix matrix1, Matrix matrix2){ 
     return matrix1 += matrix2; 
    } 

會這樣的工作?將運營商作爲班級的一部分,班級的朋友還是班級之外的人,是否更好?

任何幫助appriciated。

+0

在C++中,我們通常使用標準庫:std :: vector,std :: map等。它會更加易於修改,並且不易出錯。 – 2013-03-13 11:01:52

+0

我期望陳述'*(this-> matrix)= *(m.matrix);'不起作用,您需要明確分配內存並使用memcpy等來分配新內存。 – 2013-03-13 11:02:38

+0

我已經包含了「using namespace std;」並且在原始文件中的代碼開始處也包含「#include 」,但是當我發佈該文件時,我沒有複製它。如果這就是你的意思。 – Ole1991 2013-03-13 11:05:30

回答

1

你爲什麼要刪除其他問題? 我希望這只是一個錯誤:(看編輯在結束)

是的,你有很多問題在你的代碼,甚至在你的設計。

只給你一個想法:

你的矩陣沒有拷貝構造函數(或移動),而不是「=」了。它們是:

Matrix(const Matrix &m); 

和(移動構造函數):

Matrix(Matrix &&m); 

而且

Matrix& operator=(const Matrix &m); 
Matrix& operator=(Matrix &&m); 

如果不定義這些特殊功能,編譯器將定義它。但他們只會顯然工作。程序編譯但工作出錯(淺與深拷貝問題通過值或通過引用)。 我想你在構造函數中使用new來構建matrix私有數組。而在破壞者你delete[]matrix。每次按值傳遞Matrix時,它都會使用編譯器生成的拷貝構造函數進行拷貝,只需複製Matrix成員的值,從而複製指針matrix而不是數組的值。在通話結束時,本地副本將被破壞,並且原始矩陣被刪除!這只是衆多問題中的一個。足夠讓你坐下來,多讀一些垃圾,然後再試一次。 一個「簡單」的修復可能通過

std::vector<double> matrix; 

更換

double *matrix; 

現在,編譯器生成的函數將工作好了很多。

是的,如果你想使用[]Matrix你需要定義它。 而+=是一個二元運算符,它取一個參數(左邊總是this,指向調用它的對象的指針)。在這裏,您只需要一個帶有2個參數的免費+()或帶有一個參數的成員+()。 希望這對你有所幫助。再問一遍。

編輯: 這是否工作爲operator=

Matrix &operator=(const Matrix &m) {*matrix = *(m.matrix);} 

不,這隻會複製第一個雙倍。你需要在entery數組上循環並複製每個元素。首先你需要確定矩陣的大小是兼容的。 (如果您使用vectormatrix=m.matrix將工作。)。 a。對於拷貝構造函數修正可能是:

Matrix::Matrix(const Matrix &m): rows (m.rows), 
            columns (m.columns), 
            matrix (new double[rows* columns]) 
{ 
    for(int i = 0; i < rows; i++) 
     for(int j = 0; j < columns; j++) 
      matrix[i * columns + j] = m.matrix[i * columns + j]; 

} 

而移動:

Matrix::Matrix( Matrix &&m): rows (m.rows), 
            columns (m.columns), 
            matrix (m.matrix) 
{ 
    m.matrix=nullptr; 
    m.rows= m.columns=0; 
} 

此舉可以大大提高應對矩陣的效率,當你不關心原值,用的是例如時間對象的情況。在這種情況下,您不需要迭代複製每個數組元素:您可以簡單地竊取整個數組。關於它的好處是,在大多數情況下,編譯器會爲您自動選擇正確的變體(複製或移動)。

+0

是的,抱歉。感謝您的回覆。雖然我不允許在這一點上使用矢量,但是我會爲運算符=做一個循環。謝謝! – Ole1991 2013-03-13 11:13:37

+0

我已經爲拷貝構造函數和運算符=實現了您的和Kristian的解決方案,但是構造函數的作用是什麼?需要嗎? – Ole1991 2013-03-13 11:31:31

+0

@ Ole1991查看最近一次關於移動的編輯。 – qPCR4vir 2013-03-13 11:54:26

1
Matrix &operator=(const Matrix &m) {*(this->matrix) = *(m.matrix);} 

這將只分配LHS的第一個元素矩陣是相同RHS的第一個元素矩陣。最重要的是,這將要求兩個矩陣都用相同數量的行和列進行初始化。您可以使用memcpy或循環來分配所有元素。

Matrix(const Matrix &rhs) : matrix(0) { 
    this->matrix = new double(); 
    *(this->matrix) = *(rhs.matrix); 
} 

這會失敗,因爲您沒有爲新構建的實例的矩陣成員(除非另一個矩陣是1x1矩陣)分配足夠的內存。假設矩陣存儲在行優先順序,應該是這樣的:

Matrix(const Matrix &rhs) : matrix(0), rows(rhs.rows), columns(rhs.columns) { 
    this->matrix = new double[rows * columns]; 
    for (size_t r = 0; r < rows; r++) { 
     for (size_t c = 0; c < columsn; c++) { 
      this->matrix[r * columns + c] = rhs.matrix[r * columns + c]; 
     } 
    } 
} 

編輯:只是爲了確保,這裏是我會怎麼做賦值運算符:

Matrix &operator=(const Matrix &m) { 
    if (rows * columns != m.rows * m.columns) { 
     delete [] this->matrix; 
     this->matrix = new double[m.rows * m.columns]; 
    } 
    rows = m.rows; 
    columns = m.columns; 
    for (size_t r = 0; r < rows; r++) { 
     for (size_t c = 0; c < columsn; c++) { 
      this->matrix[r * columns + c] = m.matrix[r * columns + c]; 
     } 
    } 
    return *this; 
} 
+0

謝謝!我爲operator =做了一個循環。 – Ole1991 2013-03-13 11:14:26

+0

現在一切正常,即使是運算符+ =和運算符+的重載。謝謝:) – Ole1991 2013-03-13 11:40:13