1

使用一個構造函數和操作符重載的作品與我的目標如下創建零的2×4矩陣:如何使用靜態成員函數創建矩陣,然後使用運算符重載打印該矩陣?

Matrix::Matrix(const int noOfRowss, const int noOfCols){ 

this->noOfRows=noOfRowss; 
this->noOfColums=noOfCols; 

data= new double[noOfRows*noOfColumns]; 

    for(int i=0; i< noOfRows; i++){ 
     for(int j=0; j<noOfColumns; j++){ 
      int index = i*noOfColumns + j; 
      data[index]=0; 
     } 
    } 
} 

std::ostream& operator<<(std::ostream& output, const Matrix& rhs){ 
    for(int i=0; i< rhs.noOfRows; i++){ 
     for(int j=0; j<rhs.noOfColumns; j++){ 
      int index = i*rhs.noOfColumns + j; 
      output<<rhs.data[index]<< "\t"; 
     } 
     output<<std::endl; 
    } 
    return output; 
} 

然而,當我嘗試使用一個靜態成員函數,我得到一個分段錯誤以下代碼(見下文實施測試文件):

Matrix Matrix::Zeros(const int noOfRows, const int noOfCols){ 
    Matrix out; 
    for(int i=0; i< noOfRows; i++){ 
     for(int j=0; j<noOfCols; j++){ 
      int index = i*noOfCols + j; 
      out.data[index]=0; 
     } 
    } 
} 

我不確定如果我正確地實現靜態成員函數,我的問題是,在我的頭功能,我需要使用以下變量:

int noOfRows; 
int noOfColumns; 
double *data; 
int GetIndex(const int rowIdx, const int columnIdx) const; 

而在我的測試文件,我想實現這個靜態成員函數如下:

Matrix matrix = Matrix::Zeros(2,4); 
cout<<matrix<<endl; 

的原因,我需要保持數據的變量,因此可以在運營商< <重載函數中使用正如之前爲構造函數所做的那樣。然而,在我的靜態成員函數中嘗試了幾種不同的變體之後,我沒有像以前那樣容易地將我的矩陣存儲在數據變量中。有人有任何建議嗎?

回答

0

您需要psecify的out物體的大小,這樣的(否則,您填寫out.data出界):

Matrix Matrix::Zeros(const int noOfRows, const int noOfCols){ 
    Matrix out(noOfRows*noOfCols); // changed here 
    for(int i=0; i< noOfRows; i++){ 
     for(int j=0; j<noOfCols; j++){ 
      int index = i*noOfCols + j; 
      out.data[index]=0; 
     } 
    } 
} 

如果這樣做,這將是更安全的,至少,因爲使用Matrix::Zeros很可能通過複製或分配通過在代碼中複製來執行構建(如果未正確定義,則導致更多的段錯誤,使用默認實現導致double*指針被搞亂的編譯器)。正如Sam Varshavchik指出的那樣,使用std::vector<double>而不是double*將使這些默認實現適用於您的情況。

但是,你正在試圖解決的具體問題,我建議你只需修改你的構造函數,以使其能夠決定的默認矩陣的內容,可能會更容易:

Matrix::Matrix(const int noOfRowss, const int noOfCols, double defaultValue) 
{ 
    this->noOfRows=noOfRowss; 
    this->noOfColums=noOfCols; 

    data= new double[noOfRows*noOfColumns]; 

    for(int i=0; i< noOfRows; i++){ 
     for(int j=0; j<noOfColumns; j++){ 
      int index = i*noOfColumns + j; 
      data[index]=defaultValue; 
     } 
    } 
} 

在頭文件,你可以有:

class Matrix 
{ 
public: 
    Matrix(const int noOfRowss, const int noOfCols, double defaultValue = 0); 
    ... 
}; 

然後:

std::cout << Matrix(4,2) << std::endl; // displays a 4x2 matrix filled with zeros 
std::cout << Matrix(4,2,1) << std::endl; // displays a 4x2 matrix filled with ones 
+0

我已經在simila實現了它你如何寫在這裏。雖然'Matrix Matrix :: Ones(const int noOfRows,const int noOfCols)Matrix outO(noOfRows,noOfCols,1); return outO; }' 這使用我的構造函數,然後我可以在我的原始帖子中使用我的代碼來使用運算符<< overloading – MachoSkinny

+0

好。不要忘記三條規則,以防止在操作Matrix類時出現崩潰。 – jpo38

2

所以,我看到你的靜態函數顯然是這樣做的,首先。

Matrix output; 

但是,你表現出的構造函數代碼有兩個參數,行數和列數。

因此,我必須得出結論,你必須有一個默認的構造函數,它可能會構造一個空矩陣,並帶有一個空的data向量。

for(int i=0; i< noOfRows; i++){ 
    for(int j=0; j<noOfCols; j++){ 
     int index = i*noOfCols + j; 
     output.data[index]=0; 
    } 
} 

然後,在這裏試圖初始化缺省構造矩陣的內容,沒有一個有效初始化data構件。

這是不會有好下場......

P.S.,你可能需要閱讀這一點,太:RAII。我懷疑你們班也會在這方面有相關的問題。而不是使用double *data成員,std::vector<double>會更好,而且很可能會避免這方面的一些陷阱。