Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Beginner's Question: Overloading the subscript operator

9 views
Skip to first unread message

j...@east.sun.com

unread,
Jan 14, 1996, 3:00:00 AM1/14/96
to
Beginner's Question:

I want to create a matrix class for a two dimensional int array
that has added features like bounds checking, etc.

What I want to do is overload the [] operator such that
my matrix class can store and retrieve elements the same
way as any standard 2 dimensional array:

matrix a(10,10);

a.[0][0] = 1;
a.[0][1] = 2;

element = a.[3][4];

I can accomplish this for single dimensioned arrays, but I haven't
had any luck doing it for multi-dimenssional arrays. I'm not quite
sure what to try next.

Any help or suggestions would be greatly appreciated.

My class defintion is as follows. I'm currently using a member
function called "element" to assign and retrieve individual elements,
but, like I said, I would rather use the standard [][] notation
instead.

Thanks.

Jim

---- Beginning of code ----

#include <iostream.h>
#include <stdlib.h>

class matrix {
public:
int ub1() const;
int ub2() const;
matrix(int d1, int d2);
~matrix();
int &element(int i, int j) const;
void print() const;
private:
int **p;
int size1, size2;
};

matrix::matrix(int d1, int d2): size1(d1), size2(d2)
{
if (d1 < 1 || d2 < 1) {
cerr << "Illegal matrix size: ";
cerr << d1 << " by " << d2 << endl;
exit (1);
}

p = new int *[size1];
for (int i=0; i<size1; i++)
p[i] = new int[size2];
}

matrix::~matrix()
{
for (int i=0; i<size1; i++)
delete p[i];
delete []p;
}

int &matrix::element(int i, int j) const
{
if (i<0 || i>ub1() || j<0 || j>ub2()) {
cerr << "Illegal matrix index ";
exit (1);
}
return (p[i][j]);
}

int matrix::ub1() const
{
return(size1-1);
}

int matrix::ub2() const
{
return(size2-1);
}


main ()
{
matrix a(3, 3), b(3, 3), c(4, 4);

a.element(0,0) = 1;
a.element(0,1) = 2;
a.element(0,2) = 3;
a.element(1,0) = 4;
a.element(1,1) = 5;
a.element(1,2) = 6;
a.element(2,0) = 7;
a.element(2,1) = 8;
a.element(2,2) = 9;

cout << endl;
int i, j;
for (i=0; i<3; i++) {
for (j=0; j<3; j++) {
cout << "element(" << i << ", " << j << ") = " << a.element(i,j);
cout << endl;
}
}
cout << endl;
}

---- End of code ----

[ Articles to moderate: mailto:c++-s...@netlab.cs.rpi.edu ]
[ Read the C++ FAQ: http://www.connobj.com/cpp/cppfaq.htm ]
[ Moderation policy: http://www.connobj.com/cpp/guide.htm ]
[ Comments? mailto:c++-r...@netlab.cs.rpi.edu ]

Robert C. Martin

unread,
Jan 16, 1996, 3:00:00 AM1/16/96
to
In article <4dbol7$r...@netlab.cs.rpi.edu> j...@East.Sun.COM writes:

I want to create a matrix class for a two dimensional int array
that has added features like bounds checking, etc.

What I want to do is overload the [] operator such that
my matrix class can store and retrieve elements the same
way as any standard 2 dimensional array:

matrix a(10,10);

a.[0][0] = 1;
a.[0][1] = 2;

element = a.[3][4];

I can accomplish this for single dimensioned arrays, but I haven't
had any luck doing it for multi-dimenssional arrays. I'm not quite
sure what to try next.

The standard trick here is to have matrix::operator[] return an object
(i.e. MatrixRow) which has operator[] defined to access an element.
Thus:

element = a[3][4];

is parsed as:

(a.operator[](3)).operator[](4);

a.operator()[3] returns an object of type matrixRow.

--------------------------

However, I tend to think that this is overkill. I think that a named
method is better:

element = a.GetElement(3,4);

Or if you must use an operator, use operator()(int, int);

element = a(3,4);

--
Robert Martin | Design Consulting | Training courses offered:
Object Mentor Assoc.| rma...@oma.com | OOA/D, C++, Advanced OO
14619 N. Somerset Cr| Tel: (708) 918-1004 | Mgt. Overview of OOT
Green Oaks IL 60048 | Fax: (708) 918-1023 | Development Contracts.

Jerry Coffin

unread,
Jan 16, 1996, 3:00:00 AM1/16/96
to
j...@East.Sun.COM wrote:

>Beginner's Question:

>I want to create a matrix class for a two dimensional int array
>that has added features like bounds checking, etc.

>What I want to do is overload the [] operator such that
>my matrix class can store and retrieve elements the same
>way as any standard 2 dimensional array:

> matrix a(10,10);

> a.[0][0] = 1;
> a.[0][1] = 2;

> element = a.[3][4];

First allow me to advise against doing this. It's generally more
trouble than it's worth. Instead, if you can live with more or less
BASIC/FORTRAN style notation, you're far better off overloading the ()
operator:

template <class T>
class matrix {
T *contents;
size_t row_size, column_size;
public:
T &operator()(size_t row, size_t col) {
// depending on usage, you prefer row- or column-major order...
return t[row*column_size + column];
}
};

If you really insist on matching C style notation, you need to do a lot
of extra work to manage it -- basically you have to create an array of
arrays, so the first operator[] returns an array whose operator[] can
then be called, returning an instance of the base type.

(assuming a single dimension array class that supports a [] operator...)

template <class T>
class matrix {
array<T> *contents;
public:
// again, change as you see fit for column vs. row ordering.
matrix(size_t columns, size_t rows) {
contents = new array<T> *(columns);
for (int i=0;i<columns; i++) {
contents[i] = new array<T>(rows);
}
}

array<T> &operator[](size_t index) {
return contents[index];
}
};
Later,
Jerry.

/* I can barely express my own opinions; I certainly can't
* express anybody else's.
*
* The universe is a figment of its own imagination.
*/

0 new messages