Help on operator overload for something like matrix(row)(col)

J

Jason

Hello. I am trying to learn how operator overloading works so I wrote
a simple class to help me practice. I understand the basic opertoar
overload like + - / *, but when I try to overload more complex
operator, I get stuck.

Here's a brief description what I want to do. I want to simulate a
matrix (2D array) from a 1D array. so what I have so far is something
like this:

class Matrix
{
private:
int row, int col;
double *array_d;
public:
~Matirx()
Matrix(int r, int col); // array_d[row * col]
double operator()(int r, int c); // matrix(2,2) =
array_d[some_index]
};

Here is where I get stuck:

1. So far my class can handle something like: doube temp =
matrix(2,3)
But I want the reverse to work: matrix(2,3) = temp;
I try to expand the my operator function:
matrix(i,j) = temp => matrix(i,j).operator=(temp) =>
matrix.operator(i,j).operator=(temp)

but matrix.operator(i,j) = a double value
so [double].operator=(temp)

Do I overload my '=' operator to be something like this:

friend operator=( double val_a, double val_b)

I don't think that's right.

2. My second problem is that I want matrix(i)(j) syntax instead of
matrix(i,j) to return a double. I am think matrix(i)(j) should
be allowed because we can use things like any_2d_array[j].
I expand my function (I don't think it's right):

temp = matrix(i)(j)
=> temp = matrix.operator()(i, matrix::eek:perator()(j))

or
=> operator().(matrix(i), j)
=> operator().( matrix.operator()(i), j)

friend double operator()( matrix::eek:perator()(i), j) =>
friend double operator()( int (Matrix::*ptr)(int i), j)

----End of questions---


Here's the code I have so far:

//START
include<iostream>
using namespace std;

class Matrix
{
private:
int row, col;
double *array_d;
int (Matrix::*ptr)(int c);//function pointer for operator()(int c)
public:
Matrix(){ array_d = NULL; }
~Matrix(){ delete [] array_d; }
Matrix(int r, int c)
{
row = r; col = c;
array_d = new double[row * col];
int i = 0;
for(i = 0; i<row*col;i++) array_d = i;

ptr = &Matrix::eek:perator(); //assign function pointer
}
int operator()(int c)
{
return c;
}
// matrix(2,3) return a double => I want matrix(2)(3)
double operator()(int r, int c)
{
if((r * col + c) < row*col)
return array_d[r * col + c];
else
return 0.0;
}
//I want something like matrix(3)(4) to return a double
/*
matrix(i)(j) => operator()(matrix::eek:perator()(i), j)
friend double operator()(int (*ptr)(int c), int d)
{
cout<<"I got to here"<<endl;

}

*/
};
int main()
{
Matrix matrix(10,10);
cout<<matrix(3,3); //it's fine
// matrix(3,3) = 123.4;
// cout<< matrix(3)(3);
return 0;
}
//END
 
J

John Harrison

Jason said:
Hello. I am trying to learn how operator overloading works so I wrote
a simple class to help me practice. I understand the basic opertoar
overload like + - / *, but when I try to overload more complex
operator, I get stuck.

Here's a brief description what I want to do. I want to simulate a
matrix (2D array) from a 1D array. so what I have so far is something
like this:

class Matrix
{
private:
int row, int col;
double *array_d;
public:
~Matirx()
Matrix(int r, int col); // array_d[row * col]
double operator()(int r, int c); // matrix(2,2) =
array_d[some_index]
};

Here is where I get stuck:

1. So far my class can handle something like: doube temp =
matrix(2,3)
But I want the reverse to work: matrix(2,3) = temp;
I try to expand the my operator function:
matrix(i,j) = temp => matrix(i,j).operator=(temp) =>
matrix.operator(i,j).operator=(temp)

but matrix.operator(i,j) = a double value
so [double].operator=(temp)

Do I overload my '=' operator to be something like this:

friend operator=( double val_a, double val_b)

I don't think that's right.

No, you have to define

double& operator()(int r, int c);

because you return a reference, you can use on the lhs of assignment.

2. My second problem is that I want matrix(i)(j) syntax instead of
matrix(i,j) to return a double. I am think matrix(i)(j) should
be allowed because we can use things like any_2d_array[j].
I expand my function (I don't think it's right):


Now matrix(i)(j) is the same as

matrix.operator(i).operator(j)

So Matrix::eek:perator() must return something for which another operator() is
valid. In other words Matrix::eek:perator() must return a class which also has
operator() defined. Classes like this are called proxy classes. Like this

class Proxy
{
double& operator()(int j); // returns a reference
};

class Matrix
{
Proxy operator()(int i); // returns a proxy
};

I'll leave you too work out the details, will be a good learning exercise.

john
 
R

red floyd

Jason said:
Hello. I am trying to learn how operator overloading works so I wrote
a simple class to help me practice. I understand the basic opertoar
overload like + - / *, but when I try to overload more complex
operator, I get stuck.

Here's a brief description what I want to do. I want to simulate a
matrix (2D array) from a 1D array. so what I have so far is something
like this:

class Matrix
{
private:
int row, int col;
double *array_d;
public:
~Matirx()
Matrix(int r, int col); // array_d[row * col]
double operator()(int r, int c); // matrix(2,2) =
array_d[some_index]

Should be:

double& operator()(int r, int c);
double operator()(int r, int c) const;
 
J

Jason

John Harrison said:
Jason said:
Hello. I am trying to learn how operator overloading works so I wrote
a simple class to help me practice. I understand the basic opertoar
overload like + - / *, but when I try to overload more complex
operator, I get stuck.

Here's a brief description what I want to do. I want to simulate a
matrix (2D array) from a 1D array. so what I have so far is something
like this:

class Matrix
{
private:
int row, int col;
double *array_d;
public:
~Matirx()
Matrix(int r, int col); // array_d[row * col]
double operator()(int r, int c); // matrix(2,2) =
array_d[some_index]
};

Here is where I get stuck:

1. So far my class can handle something like: doube temp =
matrix(2,3)
But I want the reverse to work: matrix(2,3) = temp;
I try to expand the my operator function:
matrix(i,j) = temp => matrix(i,j).operator=(temp) =>
matrix.operator(i,j).operator=(temp)

but matrix.operator(i,j) = a double value
so [double].operator=(temp)

Do I overload my '=' operator to be something like this:

friend operator=( double val_a, double val_b)

I don't think that's right.

No, you have to define

double& operator()(int r, int c);

because you return a reference, you can use on the lhs of assignment.

2. My second problem is that I want matrix(i)(j) syntax instead of
matrix(i,j) to return a double. I am think matrix(i)(j) should
be allowed because we can use things like any_2d_array[j].
I expand my function (I don't think it's right):


Now matrix(i)(j) is the same as

matrix.operator(i).operator(j)

So Matrix::eek:perator() must return something for which another operator() is
valid. In other words Matrix::eek:perator() must return a class which also has
operator() defined. Classes like this are called proxy classes. Like this

class Proxy
{
double& operator()(int j); // returns a reference
};

class Matrix
{
Proxy operator()(int i); // returns a proxy
};

I'll leave you too work out the details, will be a good learning exercise.

john


Thanks. I got them to work from your advice.

The proxy classes are not too convenient if I want to overload the ()
operator for a 10-D array. I would have to define 9 additional proxy
classes:

double &Proxy9::eek:perator()(int i);
Proxy9 Proxy8::eek:perator()(int i);
Proxy8 Proxy7::eek:perator()(int i);
....
....
Proxy1 Matrix::eek:perator()(int i);

Is there a better way to do it? I know a 10-D array is a bit extreme, but
just want to learn :)
 
J

John Harrison

Thanks. I got them to work from your advice.

The proxy classes are not too convenient if I want to overload the ()
operator for a 10-D array. I would have to define 9 additional proxy
classes:

double &Proxy9::eek:perator()(int i);
Proxy9 Proxy8::eek:perator()(int i);
Proxy8 Proxy7::eek:perator()(int i);
...
...
Proxy1 Matrix::eek:perator()(int i);

Is there a better way to do it? I know a 10-D array is a bit extreme, but
just want to learn :)

Have a look at the boost multi_array class

http://www.boost.org/libs/multi_array/doc/index.html

which shows a completely different approach using templates.

john
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top