operator [] in 2d array

Hello,

i've been searching for any hints for my problem for two days. I've noticed some usefull ones, but unfortunately i still don't get it.

The problem seems to be very simple:
i've got program which calculates matrices. Firstly, i create object A which is class Matrix and load from file values to fill the matrix. Then i need to call to element pointed by indexes i and j, that is A[i][j] and then change some values in the matrix A.

What my problem is? Well, i've implemented my program in following way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Matrix
{
private:
	struct RCMatrix;
	RCMatrix* matrix;
public:
...
};

struct Matrix::RCMatrix
{
	double* data;
	int rows,columns;
	int reffCounter;
...
};


(i'm using 1D array (storing data from one row right after stored data from previous row), actually, but i need to call to it using doubled operator [][])

and now i know (actually, I think i know, but i'm not sure ;) ), that i need to create a class (let's call it Row), overload the operator [] for the first time in that class and after that i need to return overloaded value to another overload operator [] and somehow i will get to values i need.

I think, that it looks like that in theory. But i've got some troubles with its implementation. In simple words: I don't know how to write this class row :)

Is that struct RCMatrix a good idea? Or should i create class instead of it and then (in that class) nest class Row? eh, don't know how to do it in a way which i will simple understand...

Could anybody help?
I'm rather not smart person so be patient, please:)
Last edited on
closed account (D80DSL3A)
I think you may not be able to overload [][]. It is not on the list given here at the MSDN site:
http://msdn.microsoft.com/en-us/library/5tk49fh2%28v=vs.80%29.aspx

You can get almost the same thing by overloading the function call operator (), if that would suit your purpose. This simple code works:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;

struct mat
{
    double arr[64];// for example
    int cols;// length of each row
    double& operator()(int r, int c){ return arr[r*cols+c]; }// overload ()
    // ctor provides easy initialization for this example
    mat(int Cols): cols(Cols)
    {
        for(int i=0; i<64; ++i)
            arr[i] = i;
    }
};

int main()
{
    mat m(8);// rows will be 8 doubles long
    cout << m(4,3) << endl;// outputs 35 = 4*8+3
    return 0;
}
thanks for your reply:)
Well, of course it would be easier to do it that way with () operator :)

But unfortunately, I have to use the [][] way. I think it is possible to overload somehow this operator,
for ex. http://www.cplusplus.com/forum/general/1724/ here is something written about it. I'm just too little experienced or not smart enough to implement the presented method in my case.

Last edited on
No, [][] can't be overloaded. You could make [] return an object that has [] overloaded aswell, but that would be stupid.

Why do you "have" to do that? Some kinda silly homework?
Last edited on
yeah, kind of.

I've recived a cpp file with some operations on matrices and was obliged to create a class appropriate for the usage in that file.

and in that file there is a line, which i cant deal with:
S[0][0] = 1.4;

where S is a class Matrix object

maybe my way of thinking is bad at all and i should do it different at all...
Last edited on
you can overload operator () instead of operator [], here an example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Matrix{
    int rows,columns;
    double* data;
    public:
        Matrix(int r,int c):rows(r),columns(c),data(new double[r*c]){}
        //----
        double operator () (int r,int c)const{ //GET value
            return data[(columns*r)+c];}
        double& operator () (int r,int c){  //SET value
            return data[(columns*r)+c];}
};

int main(){
    Matrix mat(3,2);
    mat(2,2)=4.5;
    cout<<mat(4,5);
    return 0;
}
Last edited on
closed account (D80DSL3A)
OK. I just thought of a simple solution to this problem.
Overload [] in the Matrix class to return a double* (instead of a double) then the 2nd [] merely dereferences the returned pointer normally:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
using namespace std;

struct mat
{
    double arr[64];// for example
    int cols;// length of each row

    double* operator[](int r){ return arr + r*cols; }// overload []

    // ctor provides easy initialization for this example
    mat(int Cols): cols(Cols)
    {
        for(int i=0; i<64; ++i)
            arr[i] = i;
    }
};

int main()
{
    mat m(8);// sets m up with 8 doubles per row
    cout << m[4][3] << endl;// outputs 35 = 4*8+3 - works as rvalue
    m[5][2] = 8.5;// test for use as an lvalue
    cout << m[5][2] << endl;// gives 8.5 so lvalue test is good.
    return 0;
}
Thank u all for your help!

now, it all works fine for:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Matrix
{
private:
	struct RCMatrix;
	RCMatrix* matrix;
public:
    class Row
    {
        Matrix& _a;
        int _i;
    public:
        Row(Matrix& a, int i) : _a(a), _i(i) {}
        double& operator[](int j) { return _a.matrix->data[_i*_a.matrix->columns+j];}
            
    };

    Row operator [](int i)
    {
        return Row(*this, i);
    }
...
};
Topic archived. No new replies allowed.