#include <iostream>

///define a matrix class
///this is a large object that can hold big memory
class matrix
{
        int rows;
        int cols;
        double **mat;

        public:

        matrix( )
        {
                //default constructor
                rows = cols = 0;
                mat = 0;
        };

        //constructor
        matrix( int r, int c )
        {
                std::cout << "ctor called\n";
                rows = r;
                cols = c;
                mat = new double* [ r ];
                for( int i = 0; i < r; ++i )
                        mat[ i ] = new double [ c ];
        };

        //copy constructor -- method for initializing one matrix directly from another
        matrix( const matrix& other)
        {
                std::cout << "copy ctor called\n";
                rows = other.rows;
                cols = other.cols;
                mat = new double* [rows];
                for( int i = 0; i < rows; ++i )
                {
                        mat[i] = new double [ cols ];
                        for( int j = 0; j < cols; ++j )
                                mat[i][j] = other.mat[i][j];
                }
        };

        //destructor
        ~matrix( )
        {
                std::cout << "dtor called\n";
                for( int i = 0 ; i < rows; ++i )
                        if( mat[i] ) delete [] mat[i];
                if( mat ) delete [] mat;
                mat = 0;
        };

        ///overload operator +
        matrix operator+( const matrix &other )
        {
                std::cout << "op+ called\n";
                matrix m(other.rows, other.cols);
                for( int i = 0; i < other.rows; i++ )
                        for( int j = 0; j < other.cols; j++ )
                                m.mat[i][j] = mat[i][j] + other.mat[i][j];
                return m;
        };

        //get a matrix element
        double &element(int i, int j) { return mat[i][j]; }

};



int main( )
{
        ///initialize matrices -- bug dense matrices
        matrix M1(1000,1000), M2(1000,1000);

        for( int i = 0; i < 1000; ++i )
        {
                for( int j = 0; j < 1000; ++j )
                {
                        M1.element(i,j) = 1;
                        M2.element(i,j) = 2;
                }
        }


        ///DO the following!
        matrix M3 = M1 + M2;
        std::cout << M3.element(500,500) << '\n';
}
