overloading [ ][ ] operator

Hello
I'm a beginner in c++. my questions are:
q1. how do i overload [][] operator in c++. i am writing a template class for matrix. i want to overload the [][]operator to access the elements of a 2d array, which is expressed as 1-d array inside my template class.
however i tried by the following way, but it gives error:

template class Row
{
public:
typedef Float tFloat;
private:
int _offset;
tFloat*& _row;
int _length;
.
.
Row(tFloat*& matrixRow,int length):_row(matrixRow),_length(length),_offset(0){}

//operator overloading for 2nd dimension or column element
tFloat& operator[](int i){
//if ( i > _length + _offset) throw RangeError("Too long");
return _row[i-_offset];
}
};

template class Matrix
{
private:
typedef Matrix MSelf;
MatType *_matrix;
int _row, _col;
.
.
//overloading first dimension or the row element
Row operator[](int i)
{
//cout << "overloaded first dimension" << endl;
return Row<MatType>(&_matrix[i*_col],_col);
}
.
.};
i get the following error message:
matrix.h: In method `class Matrices::Row Matrices::Matrix::operator [](int)':
main.cpp:80: instantiated from here
matrix.h:188: initialization of non-const reference type `double *&'
matrix.h:188: from rvalue of type `double *'
matrix.h:40: in passing argument 1 of `Matrices::Row::Row(double *&, int)'

If anyone can help me, it will be very nice.

With regards
faisal



Comments

  • as far as i know, [][] operator cannot be overloaded. the line of ur code:
    [blue]Row operator[](int i);[/blue]
    cant take two parameters, so it wont act as overloaded [][].
  • hello donotalo and all others
    thnx for ur reply. [][] can b overloaded. i did it already, when the array was expressed as 2d in my class. but now i want to express 2d arrays as 1d in my class(as done in the internal memory of the computer). i think arrays of any dimension is expressed as 1-D internally in the memory. so in case any programmer want to access the 2D array, there has to be a [][] operator overloading in the compiler that allowes the access.
    anyway, if i could copy the whole code that would have been fine. i am trying to do so in my next message.
    however , i think all the information lies in the error message, which i've given in my first message, pls check and try to help me.
    with regards
    faisal
  • //******************************************************
    // file: matrix.h *
    //Contains Matrix Class with Important methods *
    //******************************************************
    #ifndef __MATRIX_H
    #define __MATRIX_H
    //******************************************************
    // included headers *
    //******************************************************

    #include
    #include
    #include


    //******************************************************
    // namespaces *
    //******************************************************

    namespace Matrices
    {

    template class Row
    {
    public:
    typedef Float tFloat;

    private:
    int _offset;
    tFloat*& _row;
    int _length;
    /*private:
    Column(){};*/

    public:
    Row(tFloat*& matrixRow,int from,int to):_row(matrixRow+from),_length(to-from),_offset(from){
    cout << "row object constructed" << endl;
    }

    Row(tFloat*& matrixRow,int length):_row(matrixRow),_length(length),_offset(0){
    //cout << "row object constructed" << endl;
    }

    tFloat& operator[](int i){
    //if ( i > _length + _offset) throw RangeError("Too long");
    return _row[i-_offset];
    }

    std::ostream& print(std::ostream& os){
    for(int i = _offset; i < _offset+_length; ++i) os << _row[i] << " ";
    return os;
    }


    //tFloat* getRow () { return _row; }

    //friend std::ostream& operator<<(std::ostream& os, Row<double> row);
    };

    templatestd::ostream& operator<<(std::ostream& os, Row<Float> row){
    return row.print(os);
    }




    //****************************************************
    // template class named Matrix *
    //****************************************************
    template class Matrix
    {

    private:
    typedef Matrix MSelf;
    MatType *_matrix;
    int _row, _col;

    public:
    //************************************************************************************
    // Constructors: there are three different constructors *
    //************************************************************************************

    //************************************************************************************
    // 1st constructor: constructs the matrix by initializing all the elements to zero *
    // ***********************************************************************************

    Matrix (int rownum, int colnum)
    {
    _matrix = new MatType [rownum*colnum];

    for (int i=0 ; i operator[](int i)
    {
    //cout << "overloaded first dimension" << endl;
    return Row<MatType>(&_matrix[i*_col],_col);
    }


    //****************************************************************************
    // overloading for '=' operator when it copies one matrix to _matrix *
    //****************************************************************************
    Matrix& operator=( const MatType **refmatrix)
    {
    for (int i=0 ; i<_row ; i++)
    {
    for (int j=0 ; j<_col ; j++) _matrix[i*_col+j] = refmatrix[i][j];
    }
    return *this;
    }

    //****************************************************************************
    // overloading for '=' operator when it copies a matrix object to _matrix *
    //****************************************************************************
    MSelf& operator= (const MSelf& matrixob)
    {
    for (int i=0 ; i<_row*_col ; i++)
    _matrix[i] = matrixob._matrix[i];
    return *this;
    }

    //***************************************************************************
    // overloading '==' operator for comparison with a reference matrix *
    //***************************************************************************
    bool operator== (const MatType **refmatrix)
    {
    for (int i=0 ; i<_row ; i++)
    {
    for (int j=0 ; j<_col ; j++)
    if (_matrix[i*_col+j] != refmatrix[i][j]) return false;
    return true;
    }
    }

    //***************************************************************************
    // overloading '==' operator for comparison with an object matrix *
    //***************************************************************************
    bool operator == (const MSelf& matrixob)
    {
    for (int i=0 ; i<_row*_col ; i++)
    if (_matrix[i] != matrixob._matrix[i]) return false;
    return true;
    }

    //**************************************************************************
    // overloading '-' operator *
    //**************************************************************************

    MSelf& operator- (const MSelf& matrixob)
    {
    MSelf* returnMatrix = new MSelf(_row, _col);

    for (int i=0 ; i<_row*_col ; i++)
    returnMatrix->_matrix[i] = _matrix[i] - matrixob._matrix[i];

    return *returnMatrix;
    }

    //*************************************************************************
    // overloading '+' operator *
    //*************************************************************************

    MSelf& operator+ (const MSelf& matrixob)
    {
    MSelf* returnMatrix = new MSelf(_row, _col);

    for (int i=0 ; i<_row*_col ; i++)
    returnMatrix->_matrix[i] = _matrix[i] + matrixob._matrix[i];

    return *returnMatrix;
    }

    //*************************************************************************
    // overloading '*' operator *
    //*************************************************************************

    MSelf& operator* (const MSelf& matrixob)
    {
    MatType tempSum;
    MSelf* returnMatrix = new MSelf(_row, matrixob._col);

    for (int i=0 ; i<_row ; i++)
    {
    for (int j=0 ; j<matrixob._col ; j++)
    {
    tempSum = 0.0;
    for (int k=0 ; k<_col ; k++)
    tempSum += _matrix[i*_col+k] * matrixob._matrix[k*matrixob._col+j];
    returnMatrix->_matrix[i*matrixob._col+j] = tempSum;
    }
    }

    return *returnMatrix;
    }


    };

    }
    #endif


    //*********************************
    // main.cpp *
    //*********************************
    #include
    #include
    #include "matrix.h"

    using namespace std;
    using namespace Matrices;

    double** Mat2;

    Mat2 = new double* [3];
    for (int i=0 ; i<3 ; i++) Mat2[i] = new double [3];


    double Mat[3][3] = {1.0, 2.0, 3.0,
    4.0, 5.0, 6.0,
    7.0, 8.0, 9.0};
    cout << "line 19 executed
    ";

    for (int i=0; i<3; i++)
    Mat2[i] = Mat[i];
    cout << "line 21 executed
    ";

    cout << Mat2[0][0] << endl;

    Matrix <double> MatOb1((const double**)Mat2, 3, 3);
    cout << "The first matrix object elements are:
    ";

    for (int i=0 ; i<MatOb1.getRows() ; i++)
    {
    for (int j=0 ; j<MatOb1.getCols() ; j++)
    cout << MatOb1[i][j] << " " ;
    cout << "
    ";
    }

    Matrix <double> MatOb2(3, 3);

    cout << "The second matrix object elements are:
    ";

    for (int i=0 ; i<MatOb2.getRows() ; i++)
    {
    for (int j=0 ; j<MatOb2.getCols() ; j++)
    cout << MatOb2[i][j] << " " ;
    cout << "
    ";
    }

    MatOb2 = MatOb1;

    cout << "The second matrix object elements after copying the first's are:
    ";

    for (int i=0 ; i<MatOb2.getRows() ; i++)
    {
    for (int j=0 ; j<MatOb2.getCols() ; j++)
    cout << MatOb2[i][j] << " " ;
    cout << "
    ";
    }


    Matrix <double> MatOb3(3, 3);

    cout << "The third matrix object elements are:
    ";

    for (int i=0 ; i<MatOb3.getRows() ; i++)
    {
    for (int j=0 ; j<MatOb3.getCols() ; j++)
    cout << MatOb3[i][j] << " " ;
    cout << "
    ";
    }

    MatOb3 = MatOb1 + MatOb2;

    cout << "The third matrix object elements after addition are:
    ";

    for (int i=0 ; i<MatOb3.getRows() ; i++)
    {
    for (int j=0 ; j<MatOb3.getCols() ; j++)
    cout << MatOb3[i][j] << " " ;
    cout << "
    ";
    }


    MatOb3 = MatOb3 - MatOb2;

    cout << "The third matrix object elements after subtraction are:
    ";

    for (int i=0 ; i<MatOb3.getRows() ; i++)
    {
    for (int j=0 ; j<MatOb3.getCols() ; j++)
    cout << MatOb3[i][j] << " " ;
    cout << "
    ";
    }

    MatOb3 = MatOb1*MatOb2;

    cout << "The third matrix object elements after multiplication are:
    ";

    for (int i=0 ; i<MatOb3.getRows() ; i++)
    {
    for (int j=0 ; j<MatOb3.getCols() ; j++)
    cout << MatOb3[i][j] << " " ;
    cout << "
    ";
    }


    double* pointer;
    pointer = MatOb1.getTransposed();

    cout << "

    The transposed matrix is
    ";
    for (int i=0 ; i<MatOb1.getCols() ; i++)
    {
    for (int j=0 ; j<MatOb1.getRows() ; j++)
    cout << pointer[i*MatOb1.getRows()+j] << " ";
    cout << "
    ";
    }


    double* row;

    cout << MatOb1[1] << " are the elements of 2nd row
    ";
    // std::cout << MatOb[1] << "Should give line 21" << std::endl;
    std::cout<<MatOb1[1][0] <<" is element of 2nd row and 1st column"<<std::endl;

    return 0;
    }

    however this is the error message i get after compiling with g++ :

    matrix.h: In method `class Matrices::Row<double> Matrices::Matrix::operator [](int)':
    main.cpp:80: instantiated from here
    matrix.h:188: initialization of non-const reference type `double *&'
    matrix.h:188: from rvalue of type `double *'
    matrix.h:40: in passing argument 1 of `Matrices::Row::Row(double *&, int)'

    it would be very kind of you, when anyone can help me.

    with regards
    faisal
  • i am a beginner and still dont understand how u can overload [][] operator! also, i couldnt understand others code well. however,
    [code]
    Row operator[](int i)
    {
    //cout << "overloaded first dimension" << endl;
    return Row<MatType>([red]&[/red]_matrix[i*_col],_col);
    }
    [/code]
    what is that [red]&[/red] doing there? as far as i understand, each of the _matrix[x] is of type [blue]MatType *[/blue] and the constructor require reference of pointer to type [blue]tFloat[/blue]. to pass by reference, u dont require the [blue]&[/blue]. try removing that [red]&[/red] from the code.
  • : i am a beginner and still dont understand how u can overload [][] operator! also, i couldnt understand others code well. however,
    : [code]
    : Row operator[](int i)
    : {
    : //cout << "overloaded first dimension" << endl;
    : return Row<MatType>([red]&[/red]_matrix[i*_col],_col);
    : }
    : [/code]
    : what is that [red]&[/red] doing there? as far as i understand, each of the _matrix[x] is of type [blue]MatType *[/blue] and the constructor require reference of pointer to type [blue]tFloat[/blue]. to pass by reference, u dont require the [blue]&[/blue]. try removing that [red]&[/red] from the code.
    :

    The result is passed as value, which probably means that & makes even less sence.

    As for any problems with the code: if you want anyone to help you out with that much code, post it between code tags:

    [leftbr]code[rightbr]
    Code here...
    [leftbr]/code[rightbr]

    I think most people reading the boards does like me when they see that much unformatted code: just shake their heads and skip the post.
  • hello all
    sorry, i am new to such type of forums, so i don know much of the rules like how to send the codes.
    anyway i tried removing & before, it doesnt help, then it cant decide which constructor to choose.
    if anybody knows how to solve the problem, pls help me.
    with regards
    faisal
    n.b. : for reference pls look at the code, that was posted before
  • : : [code]
    : : Row operator[](int i)
    : : {
    : : //cout << "overloaded first dimension" << endl;
    : : return Row<MatType>([red]&[/red]_matrix[i*_col],_col);
    : : }
    : : [/code]
    : : what is that [red]&[/red] doing there? as far as i understand, each of the _matrix[x] is of type [blue]MatType *[/blue] and the constructor require reference of pointer to type [blue]tFloat[/blue]. to pass by reference, u dont require the [blue]&[/blue]. try removing that [red]&[/red] from the code.
    : :
    :
    : [red]The result is passed as value[/red], which probably means that & makes even less sence.

    please make me clear if i dont understand ur point. from the code given, i found two constructors:

    1. Row(tFloat*& matrixRow,int from,int to)
    2. Row(tFloat*& matrixRow,int length)

    so my question is how the [blue]tFloat*&[/blue] makes passing argument by value? from my view, i understand that [blue]matrixRow[/blue] is a [red]pointer to tFloat[/red] which is passing by [red]reference[/red] and hence no need of any extra [blue]&[/blue] when calling these constructors.

    to faisal_ahmedbd, sorry dont understand what is going on. if u use default argument to [blue]to[/blue] in the first constructor, then u get constructor confusion error.
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories