-2

I don't really know how to check the size of both matrices, if they are appropriate to be added. Here's my code, which is currently running without errors:

matrix operator+(const matrix & mat){
    matrix add;
    add.mSize = mat.mSize;
    add.mP = new int[add.mSize * add.mSize];
    for(int i = 0; i < add.mSize * add.mSize; i++){
        add.mP[i] = mP[i] + mat.mP[i];
    }
    return add;                        
}

1 Answers1

2

A general 2d matrix has two different dimensions, rows and columns (unless it is the particular case of a square matrix).

In the general case, your code could be:

#include <stdexcept>

class matrix
{
public:
    matrix(int rows, int columns) :
        mRows(rows), mColumns(columns), mP(NULL)
    {
        mP = new double[mRows * mColumns];
        for (int i = 0; i < mRows * mColumns; i++)
            mP[i] = 0.0;
    }

    matrix(const matrix& other) :
        mRows(other.mRows), mColumns(other.mColumns), mP(NULL)
    {
        mP = new double[mRows * mColumns];
        for (int i = 0; i < mRows * mColumns; i++)
            mP[i] = other.mP[i];
    }

    ~matrix()
    {
        delete[] mP;
    }

    const double* operator[] (int row) const {
        return &mP[row * mColumns];
    }

    double* operator[] (int row) {
        return &mP[row * mColumns];
    }

    matrix& operator=(const matrix& other) {
        if (this == &other) return *this;
        if ((mRows != other.mRows) || (mColumns != other.mColumns)) throw std::invalid_argument( "dimensions don't match" );
        for (int r = 0; r < mRows; r++) {
            for (int c = 0; c < mColumns; c++) {
                (*this)[r][c] = other[r][c];
            }
        }
        return *this;
    }

    matrix& operator+=(const matrix& other) {
        if ((mRows != other.mRows) || (mColumns != other.mColumns)) throw std::invalid_argument( "dimensions don't match" );
        for (int r = 0; r < mRows; r++) {
            for (int c = 0; c < mColumns; c++) {
                (*this)[r][c] += other[r][c];
            }
        }
        return *this;
    }

private:
    int mRows;
    int mColumns;
    double *mP;
};

inline matrix operator+(matrix lhs, const matrix& rhs)
{
    lhs += rhs;
    return lhs;
}
Marco Pantaleoni
  • 2,529
  • 15
  • 14
  • Not too shabby, but `double* operator[] (int row) const` leaves a pointer that can be used to change the contents of `matrix` in the hands of the caller, violating the spirit of a `const` method, and [The Rule of Three](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) has been violated. – user4581301 Apr 18 '18 at 17:26
  • Thanks for the heads up. Fixed the Rule of Three, and improved a bit the `operator[]`. TBH actual code would encapsulate the row returned by `operator[]` but probably it would become too large and adding little to this discussion. – Marco Pantaleoni Apr 18 '18 at 17:53
  • When I need to do a `const` accessor for a matrix like this it looks something like `double operator()(int row, int column) const { return mP[row * mColumns + column]; }` non-`const` version is identical other than returning a reference. Wee bit less vulnerable to mis-use. Good write-up over here: https://isocpp.org/wiki/faq/operator-overloading#matrix-subscript-op – user4581301 Apr 18 '18 at 18:07