Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > overloading [][]

Reply
Thread Tools

overloading [][]

 
 
John Harrison
Guest
Posts: n/a
 
      08-24-2003
>
> Well the two dim array is supposed to be in the Matrix class. The proxy
> class just hold a reference to the matrix and the first index.
>
> Something like this (untested code)
>
> class Matrix;
>
> class Proxy
> {
> friend class Matrix;
> double& operator[](int j) { return m.matrix[i][j]; }
> private:
> Proxy(Matrix& mm, int ii) : m(mm), i(ii) {}
> Matrix& m;
> int i;
> };
>
> class Matrix
> {
> friend class Proxy;
> public:
> Proxy operator[](int i) { return Proxy(*this, i); }
> private:
> double** matrix;
> };
>


Actually that could be better, in this case all that is needed is for Proxy
to hold a double*.

class Matrix;

class Proxy
{
friend class Matrix;
double& operator[](int j) { return ptr[j]; }
private:
Proxy(double* p) : ptr(p) {}
double* ptr;
};

class Matrix
{
public:
Proxy operator[](int i) { return Proxy(matrix[i]); }
private:
double** matrix;
};

Which I think was what Sim was getting at.

john


 
Reply With Quote
 
 
 
 
Josh Sebastian
Guest
Posts: n/a
 
      08-25-2003
On Mon, 25 Aug 2003 04:28:43 +1000, Andre wrote:

> Hi,
>
> I have a class which contains a two-dimensional array. I need to
> overload something like the [][] operator so that I'm able to access the
> internal array elements via the class object. For example:
>
> Matrix a = new Matrix(10,10);
>
> a[1][1] = 6;
>
> Is this possible? How can I simulate a two dimensional array using a
> class in c++? Thanks


If you don't mind the syntax (some people even like it better), you can
instead provide an operator() that takes two indexes.

a(1, 1) = 6;

It would look something like

class Matrix {
// ...
int& operator()(int row, int col);
int operator()(int row, int col) const;
};

Josh
 
Reply With Quote
 
 
 
 
John Carson
Guest
Posts: n/a
 
      08-25-2003
"John Harrison" <(E-Mail Removed)> wrote in message
news:bib1jv$798kd$(E-Mail Removed)-berlin.de
> "Andre" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> > Hi,
> >
> > I have a class which contains a two-dimensional array. I need to
> > overload something like the [][] operator so that I'm able to
> > access the internal array elements via the class object. For
> > example:
> >
> > Matrix a = new Matrix(10,10);
> >
> > a[1][1] = 6;
> >
> > Is this possible? How can I simulate a two dimensional array using a
> > class in c++? Thanks
> >
> > -Andre
> >

>
> There is no operator[][], there is only the operator[]. You can do
> what you want with a proxy class, something like this
>
> class Proxy
> {
> public:
> double operator[](int j) const;
> double& operator[](int j);
> };
>
> class Matrix
> {
> public:
> const Proxy operator[](int i) const;
> Proxy operator[](int i);
> };
>
> I hope you get the idea, you overload operator[] on your Matrix
> object to return another class (the Proxy class), you then overload
> operator[] on the proxy class to return a Matrix element.
>
> john



There may be good reasons for using a proxy class, but if the matrix is
stored internally as

double **matrix;

as per your later examples, then you can implement a double subscript
operator by simply having the following in the Matrix class:

public:
double * operator[](int i)
{ return matrix[i]; }
const double * operator[](int i) const
{ return matrix[i]; }

The built in [] operator will do the rest.


--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)

 
Reply With Quote
 
Immanuel Albrecht
Guest
Posts: n/a
 
      08-30-2003
"John Harrison" <(E-Mail Removed)> wrote in
news:bib7vu$7j6lp$(E-Mail Removed)-berlin.de:

First of all, sorry for being late, I was at vacation...

> If you return a reference, then you have to have an object to refer
> to. Where do you propose to store that object?

Of course, in your Matrix class your object should be stored.
> I think its well known
> that this scheme is impossible to implement correctly and safely. See
> for instance Effective C++ by Scott Meyer who gives all the various
> flawed possibilities a good going over.


I'm sorry, but I haven't read this book.
>
> Unless of course you have some code that shows differently ...


So what's wrong with e.g. this:


#include <iostream>
#include <ostream>

#include <vector>

template <int rows,int cols> class Matrix
{
private:
double mat[rows][cols];
public:
class Proxy {
private:
Matrix* m;
int row;

friend class Matrix;

void SetRow(int r)
{ row = r;}

void SetMat(Matrix* matrix)
{ m = matrix;}

public:
Proxy() {}

const double& operator [](int i) const;
double& operator [](int i);

};

friend class Proxy;
private:
std::vector<Proxy> prox;

public:

Matrix() : prox(rows)
{
for (unsigned int r=0;r<rows;r++)
{
prox[r].SetRow(r);
prox[r].SetMat(this);
}
}

const Proxy& operator[] (int i) const
{
return prox[i];
}

Proxy& operator[] (int i)
{
return prox[i];
}

};

template <int rows, int cols>
const double& Matrix<rows,cols>:roxy:perator[](int i) const
{
return m->mat[row][i];
}

template <int rows, int cols>
double& Matrix<rows,cols>:roxy:perator[](int i)
{
return m->mat[row][i];
}



int main()
{
Matrix<4,4> m;

for (unsigned int r=0;r<4;r++)
for (unsigned int c=0;c<4;c++)
{
std::cout << r << " " << c <<std::endl;
m[r][c] = r+c;
}

for (unsigned int r=0;r<4;r++)
{
for (unsigned int c=0;c<4;c++)
std::cout << m[r][c] << " ";

std::cout << std::endl;
}


return 0;
}
 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      08-30-2003

"Immanuel Albrecht" <(E-Mail Removed)> wrote in message
news:biq3ak$4pn$07$(E-Mail Removed)-online.com...
> "John Harrison" <(E-Mail Removed)> wrote in
> news:bib7vu$7j6lp$(E-Mail Removed)-berlin.de:
>
> First of all, sorry for being late, I was at vacation...
>
> > If you return a reference, then you have to have an object to refer
> > to. Where do you propose to store that object?

> Of course, in your Matrix class your object should be stored.
> > I think its well known
> > that this scheme is impossible to implement correctly and safely. See
> > for instance Effective C++ by Scott Meyer who gives all the various
> > flawed possibilities a good going over.

>
> I'm sorry, but I haven't read this book.
> >
> > Unless of course you have some code that shows differently ...

>
> So what's wrong with e.g. this:
>
>
> #include <iostream>
> #include <ostream>
>
> #include <vector>
>
> template <int rows,int cols> class Matrix
> {
> private:
> double mat[rows][cols];
> public:
> class Proxy {
> private:
> Matrix* m;
> int row;
>
> friend class Matrix;
>
> void SetRow(int r)
> { row = r;}
>
> void SetMat(Matrix* matrix)
> { m = matrix;}
>
> public:
> Proxy() {}
>
> const double& operator [](int i) const;
> double& operator [](int i);
>
> };
>
> friend class Proxy;
> private:
> std::vector<Proxy> prox;
>
> public:
>
> Matrix() : prox(rows)
> {
> for (unsigned int r=0;r<rows;r++)
> {
> prox[r].SetRow(r);
> prox[r].SetMat(this);
> }
> }
>
> const Proxy& operator[] (int i) const
> {
> return prox[i];
> }
>
> Proxy& operator[] (int i)
> {
> return prox[i];
> }
>
> };
>
> template <int rows, int cols>
> const double& Matrix<rows,cols>:roxy:perator[](int i) const
> {
> return m->mat[row][i];
> }
>
> template <int rows, int cols>
> double& Matrix<rows,cols>:roxy:perator[](int i)
> {
> return m->mat[row][i];
> }
>
>
>
> int main()
> {
> Matrix<4,4> m;
>
> for (unsigned int r=0;r<4;r++)
> for (unsigned int c=0;c<4;c++)
> {
> std::cout << r << " " << c <<std::endl;
> m[r][c] = r+c;
> }
>
> for (unsigned int r=0;r<4;r++)
> {
> for (unsigned int c=0;c<4;c++)
> std::cout << m[r][c] << " ";
>
> std::cout << std::endl;
> }
>
>
> return 0;
> }


Well you've answered my point

> > If you return a reference, then you have to have an object to refer
> > to. Where do you propose to store that object?


by creating a vector of proxys. But that's an overhead for every matrix to
carry around. Arguably its a small amount of space compared to the matrix as
a whole. Whether your method is better than copying the Proxy class as I
suggested would depend on the application I think. In any case, as John
Carson pointed out, this time the proxy class need only be a pointer, which
is better than both our methods.

john


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
RE: Overloading __init__ & Function overloading Iyer, Prasad C Python 4 09-30-2005 08:01 PM
Re: Overloading __init__ & Function overloading Fredrik Lundh Python 0 09-30-2005 03:59 PM
Overloading __init__ & Function overloading Iyer, Prasad C Python 3 09-30-2005 02:17 PM
Re: Overloading __init__ & Function overloading Steve Holden Python 0 09-30-2005 01:58 PM
Re: Overloading __init__ & Function overloading Fredrik Lundh Python 0 09-30-2005 01:53 PM



Advertisments