使用 OOP 在 C++ 中添加矩阵

Addition of Matrix in C++ using OOP

以下代码没有给出正确的输出。矩阵数据显示完美,但添加两个对象 M1 和 M2 后,它没有显示正确的输出。如果我使用 setData 在矩阵中输入数据,数据会完美存储,但加法操作不正确。请向我建议如何纠正这个逻辑错误?

#include <iostream>
#include <string.h>
using namespace std;

class Matrix{
    private:
        void Allocate();
        int noOfRows;
        int noOfColumns;
        int **data;
    public:
        Matrix(int noOfRows, int noOfColumns);
        void setData();
        void displayData();
        ~Matrix();
        Matrix (const Matrix &ref);
        Matrix operator + (const Matrix &m);
        void operator = (const Matrix &M );
        Matrix& operator = (int x);
};

Matrix::Matrix(int inr=0, int inc=0){
    noOfRows=inr; noOfColumns=inc;
    Allocate();
}

Matrix::Matrix (const Matrix &ref){
    Allocate();
    for(int r=0;r<ref.noOfRows;r++)
        for(int c=0;c<ref.noOfColumns;c++)
            data[r][c]=ref.data[r][c];
}

void Matrix :: operator = (const Matrix &M ) { 
    Allocate();
        noOfRows = M.noOfRows;
        noOfColumns = M.noOfColumns;
        data=M.data;
      }

Matrix& Matrix :: operator = (int x){
    Allocate();
    for(int r=0;r<noOfRows;r++)
        for(int c=0;c<noOfColumns;c++)
            data[r][c]=x;
        return *this;
      }

void Matrix::Allocate(){
    data=new int*[noOfRows];
    for(int i=0;i<noOfRows;i++)
        data[i]=new int[noOfColumns]();
}

void Matrix::setData(){
    for(int r=0;r<noOfRows;r++){
        for(int c=0;c<noOfColumns;c++){
            cout<<"Enter ...";cin>>data[r][c];
        }
    cout<<endl; 
    }
}

Matrix Matrix::operator + (const Matrix &m){
    Matrix ms(m.noOfRows,m.noOfColumns);
    for (int i=0; i<m.noOfRows; i++) 
        for (int j=0; j<m.noOfColumns; j++)
        ms.data[i][j] = data[i][j]+m.data[i][j];
    
    return ms;
    }

void Matrix::displayData(){
    for(int r=0;r<noOfRows;r++){
        for(int c=0;c<noOfColumns;c++)
            cout<<data[r][c]<<"\t";
        cout<<endl;
    }
}

Matrix::~Matrix(){
    for (int i = 0; i < noOfRows; ++i)
        delete[] data[i];
    delete [] data;
}

int main(){
    Matrix M3(2,2);M3=0;
    Matrix M1(2,2);M1=1;
    Matrix M2(2,2);M2=2;
//M1.setData();M2.setData();M3.setData();   
    cout<<"\n Matrix A = "<<endl;
    M1.displayData();
    cout<<"\n Matrix B = "<<endl;
    M2.displayData();
    cout<<"\n Matrix C = "<<endl;
    M3 = M1;
    M3.displayData();
    cout<<"\n Sum of Matrix = "<<endl;
    M3 = M1 + M2;
    M3.displayData();

    return 0;
}

Output is here for detail

复制构造函数和赋值运算符都被破坏了。让我们快速浏览一下,看看哪里出了问题

Matrix::Matrix (const Matrix &ref){
    // noOfRows and noOfColumns have not been initialized. Their values are unknown so 
    // the rest of this function is a crapshoot. Could do anything.
    Allocate();
    for(int r=0;r<ref.noOfRows;r++)
        for(int c=0;c<ref.noOfColumns;c++)
            data[r][c]=ref.data[r][c];
}

// An assignment operator is expected to return Matrix &
void Matrix :: operator = (const Matrix &M ) { 
    // noOfRows and noOfColumns have not been updated. Could be wrong, resulting in 
    // allocate allocating the wrong amount of storage. Moot point since this 
    // allocation is never used. See below.
    Allocate();
        noOfRows = M.noOfRows;
        noOfColumns = M.noOfColumns;
        data=M.data; // both instances share M's data. This will fail sooner or later
                     // If the program lives long enough, both instances will go out
                     // of scope and double delete the allocation.
                     // Also leaks allocation pointed at by `data`.
      }

我很匆忙,所以我没有考虑修复赋值运算符,只是使用了 the Copy and Swap Idiom。很可能有更有效的解决方案,但复制和交换通常足够快并且几乎不可能出错。这是一个很好的起点,基准测试会告诉您它是否有问题。

Matrix::Matrix(const Matrix &ref):
        noOfRows(ref.noOfRows),
        noOfColumns(ref.noOfColumns) // initialize row and columns
{
    Allocate(); // now safe to use
    for (int r = 0; r < ref.noOfRows; r++)
        for (int c = 0; c < ref.noOfColumns; c++)
            data[r][c] = ref.data[r][c];
}

Matrix& Matrix::operator =(Matrix M) // correct return type, and does the heavy
                                     // lifting with the copy constructor
{
    std::swap(noOfRows, M.noOfRows);
    std::swap(noOfColumns, M.noOfColumns);
    std::swap(data, M.data);
    return *this;
}