-1

I'm trying to implement a generic "Matrix" class using operator overloading to perform certain arithmetic operations but the programme takes elements of the matrix as input without any output generated. I'm not sure if the issue lies within my overloaded output operator or other functions. I'd appreciate any assistance regarding this issue. Thank you! :)

#include<iostream>
#include<cmath>

using namespace std;

class Matrix

{

    int NumberOfRows;
    int NumberOfColumns;

    public:

        int** UserMatrix;

            Matrix()

            {

                this->NumberOfRows=0;
                this->NumberOfColumns=0;
                this->UserMatrix=NULL;

            }

            Matrix(int Rows, int Columns)

            {

                this->NumberOfRows=Rows;
                this->NumberOfColumns=Columns;
                this->UserMatrix=new int*[this->NumberOfRows];
                for(int i=0; i<this->NumberOfRows; i++)
                {
                    this->UserMatrix[i]=new int[this->NumberOfColumns];
                }

            }

            Matrix(const Matrix &Copy)

            {

                this->NumberOfRows=Copy.NumberOfRows;
                this->NumberOfColumns=Copy.NumberOfColumns;
                this->UserMatrix=Copy.UserMatrix;
            }

            int getRows()

            {

                return this->NumberOfRows;

            }

            int getColumns()

            {

                return this->NumberOfColumns;

            }

            Matrix& operator=(const Matrix &Copy)

            {

                    this->NumberOfRows=Copy.NumberOfRows;
                    this->NumberOfColumns=Copy.NumberOfColumns;
                    for(int i=0; i<this->NumberOfRows; i++)
                    {
                        for(int j=0; j<this->NumberOfColumns; j++)
                        {
                            this->UserMatrix[i][j]=Copy.UserMatrix[i][j];
                        }
                    }

                return *this;

            }

            Matrix& operator+(const Matrix &Copy)

            {

                Matrix Sum;
                    for(int i=0; i<this->NumberOfRows; i++)
                    {
                        for(int j=0; j<this->NumberOfColumns; j++)
                        {
                            Sum.UserMatrix[i][j]=this->UserMatrix[i][j]+Copy.UserMatrix[i][j];
                        }
                    }

                return Sum;

            }

            Matrix& operator-(const Matrix &Copy)

            {

                Matrix Difference;
                    for(int i=0; i<this->NumberOfRows; i++)
                    {
                        for(int j=0; j<this->NumberOfColumns; j++)
                        {
                            Difference.UserMatrix[i][j]=this->UserMatrix[i][j]-Copy.UserMatrix[i][j];
                        }
                    }

                return Difference;

            }

            Matrix& operator*(const Matrix &Copy)

            {

                Matrix Multiply;
                    for(int i=0; i<this->NumberOfRows; i++)
                    {
                        for(int j=0; j<this->NumberOfColumns; j++)
                        {
                            Multiply.UserMatrix[i][j]=this->UserMatrix[i][j]*Copy.UserMatrix[i][j];
                        }
                    }

                return Multiply;

            }

            bool operator==(const Matrix &Copy)

            {

                    if(Copy.NumberOfRows!=this->NumberOfRows || Copy.NumberOfColumns!=this->NumberOfColumns)
                    {
                        return false;
                    }
                    for(int i=0; i<this->NumberOfRows; i++)
                    {
                        for(int j=0; j<this->NumberOfColumns; j++)
                        {
                            if(this->UserMatrix[i][j]!=Copy.UserMatrix[i][j]);
                            {
                                return false;
                            }
                        }
                    }

                return true;

            }

            Matrix& operator+=(int X)

            {
                
                Matrix Add;
                    for(int i=0; i<this->NumberOfRows; i++)
                    {
                        for(int j=0; j<this->NumberOfColumns; j++)
                        {
                            Add.UserMatrix[i][j]=this->UserMatrix[i][j]+X;
                        }
                    }

                return Add;

            }

            Matrix& operator-=(int X)

            {
                
                Matrix Subtract;
                    for(int i=0; i<this->NumberOfRows; i++)
                    {
                        for(int j=0; j<this->NumberOfColumns; j++)
                        {
                            Subtract.UserMatrix[i][j]=this->UserMatrix[i][j]-X;
                        }
                    }

                return Subtract;

            }

            Matrix& operator*=(int X)

            {
                
                Matrix Multiply;
                    for(int i=0; i<this->NumberOfRows; i++)
                    {
                        for(int j=0; j<this->NumberOfColumns; j++)
                        {
                            Multiply.UserMatrix[i][j]=this->UserMatrix[i][j]*X;
                        }
                    }

                return Multiply;

            }

            Matrix& operator/=(int X)

            {
                
                Matrix Divide;
                    for(int i=0; i<this->NumberOfRows; i++)
                    {
                        for(int j=0; j<this->NumberOfColumns; j++)
                        {
                            Divide.UserMatrix[i][j]=this->UserMatrix[i][j]/X;
                        }
                    }

                return Divide;

            }

            Matrix& operator()(int A, int B)

            {

                Matrix New;
                    New.UserMatrix=new int*[A];
                    for(int i=0; i<NumberOfRows; i++)
                    {
                        New.UserMatrix[i]=new int[B];
                    }

                return New;

            }

            ~Matrix()
            
            {

                for(int i=0; i<this->NumberOfRows; i++)
                {
                    delete[] this->UserMatrix[i];
                }
                delete[] this->UserMatrix;

            }

};

istream& operator>>(istream& Input, Matrix &Copy)

{

        for(int i=0; i<Copy.getRows(); i++)
        {
            for(int j=0; j<Copy.getColumns(); j++)
            {
                Input >> Copy.UserMatrix[i][j];
            }
        }

    return Input;

}

ostream& operator<<(ostream& Output, Matrix &Copy)

{

        for(int i=0; i<Copy.getRows(); i++)
        {
            for(int j=0; j<Copy.getColumns(); j++)
            {
                Output << Copy.UserMatrix[i][j] << "\t";
            }
            Output << endl;
        }

    return Output;

}


            
int main()

{

    Matrix M1(2, 2), M2(2, 2); //declare multiple 3X3 matrices
        cin >> M1;
        cin >> M2;
    Matrix M4=M1+M2; //should be able to write expressions of this
    Matrix M5=M1(1,2); //returns a matrix of size 1X2 starting from row-0
        cout << M4;
    

    return 0;

}
  • It sounds like you may need to learn how to use a debugger to step through your code. With a good debugger, you can execute your program line by line and see where it is deviating from what you expect. This is an essential tool if you are going to do any programming. Further reading: [How to debug small programs](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/) and [Debugging Guide](http://idownvotedbecau.se/nodebugging/) – NathanOliver May 25 '22 at 15:10
  • Deadly sin in copy constructor: `this->UserMatrix=Copy.UserMatrix;` – this will lead to double deletion of the data provided you fix the memory leak for not having a destructor. You get around all that trouble if you use `std::vector` instead – if doing so, then even default copy and move constructor and assignment are fine – and default destructor... – Aconcagua May 25 '22 at 15:12
  • A one-dimensional array (no matter if raw or hidden behind `std::vector` is more efficient; though you'd need to calculate the index offsets explicitly (`rowIndex * numberOfColumns + columnIndex`). – Aconcagua May 25 '22 at 15:14
  • Your assignment operator does not re-allocate any memory if sizes differ – if previous content was smaller UB due to accessing array indices out of bounds. – Aconcagua May 25 '22 at 15:17
  • A minor one, but correct datatype for specifying sizes or lengths in C++ is `size_t`, not `int`. – Aconcagua May 25 '22 at 15:17
  • You should prefer c++ *keywords* (`nullptr`) over old (obsolete) C *macros* (`NULL`). – Aconcagua May 25 '22 at 15:19
  • You should get used to implement the constructor's initialiser list (not to be confused with `std::initializer_list`): `Matrix() : NumberOfRows(0), NumberOfColumns(0), UserMatrix(nullptr) { }` – this prefers direct initialisation by value over default initialisation + assignment; the latter can have a significant overhead for complex types; more important: some types (references, const members, non-default-constructable types, ...) *only* can be initialised that way. – Aconcagua May 25 '22 at 15:31
  • About [`using namespace std`](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice)... – Aconcagua May 25 '22 at 16:17
  • `userData` absolutely should be a private member – otherwise users of your class might change the array in an illegal way (e.g. deleting sub-arrays and so on). To provide access to the individual cells then you might implement your own index `operator[]`. – Aconcagua May 25 '22 at 16:19

0 Answers0