Overloading operator []

M

md

Hi,
the following code is working for static objects.
ie the statement IntArray x(20);
my problem is i want to use this overloading operator [] for
dynamically created objects
for example the statement IntArray *x;

Please give me some help regarding this
//////////////////////////////////////////////////////////////////////////////////////////////////////////
class IntArray
{
public:
IntArray(int size = 1); // default size: 1 int
IntArray(IntArray const &other);
~IntArray();
IntArray const &operator=(IntArray const &other);

// overloaded index operators:
int &operator[](int index); // first
int operator[](int index) const; // second

private:
void destroy(); // standard functions
// used to copy/destroy
void copy(IntArray const &other);

int
*data,
size;
};

IntArray::IntArray(int sz)
{
if (sz < 1)
{
cout << "IntArray: size of array must be >= 1, not " << sz
<< "!" << endl;
exit(1);
}
// remember size, create array
size = sz;
data = new int [sz];
}
// copy constructor
IntArray::IntArray(IntArray const &other)
{
copy(other);
}

// destructor
IntArray::~IntArray()
{
delete [] data;
}

// overloaded assignment
IntArray const &IntArray::eek:perator=(IntArray const &other)
{
// take action only when no auto-assignment
if (this != &other)
{
delete [] data;
copy(other);
}
return (*this);
}

// copy() primitive
void IntArray::copy(IntArray const &other)
{
// set size
size = other.size;

// create array
data = new int [size];

// copy other's values
for (register int i = 0; i < size; i++)
data = other.data;
}

// here is the overloaded array operator
int &IntArray::eek:perator[](int index)
{

// check for array boundary over/underflow
if (index < 0 || index >= size)
{
cout << "IntArray: boundary overflow or underflow, index =
"
<< index << ", should range from 0 to " << size - 1 <<
endl;
exit(1);
}
return (data[index]); // emit the reference
}

int main()
{
IntArray x(20); // 20 ints //statement 1

for (int i = 0; i < 20; i++)
x = i * 2; // assign the elements

// produces boundary
// overflow
for (int i = 0; i <= 20; i++)
cout << "At index " << i << ": value is " << x << endl;

return (0);
}
///////////////////////////////////////////////////////////////////////////////////////

With Warm Regards,
Murali.
 
M

mlimber

md said:
Hi,
the following code is working for static objects.
ie the statement IntArray x(20);
my problem is i want to use this overloading operator [] for
dynamically created objects
for example the statement IntArray *x;
[snip code]

First, prefer std::vector to rolling your own. Second, what's the
problem? I don't see anything wrong with your second statement prima
facies, except that it is unintialized and of course I would generally
prefer a smart pointer (e.g. std::auto_ptr) to a raw pointer for any
dynamically allocated object.

Cheers! --M
 
J

John Carson

md said:
Hi,
the following code is working for static objects.
ie the statement IntArray x(20);
my problem is i want to use this overloading operator [] for
dynamically created objects
for example the statement IntArray *x;

Please give me some help regarding this
//////////////////////////////////////////////////////////////////////////////////////////////////////////
class IntArray
{
public:
IntArray(int size = 1); // default size: 1 int
IntArray(IntArray const &other);
~IntArray();
IntArray const &operator=(IntArray const &other);

// overloaded index operators:
int &operator[](int index); // first
int operator[](int index) const; // second

private:
void destroy(); // standard functions
// used to copy/destroy
void copy(IntArray const &other);

int
*data,
size;
};

IntArray::IntArray(int sz)
{
if (sz < 1)
{
cout << "IntArray: size of array must be >= 1, not " << sz
<< "!" << endl;
exit(1);
}
// remember size, create array
size = sz;
data = new int [sz];
}
// copy constructor
IntArray::IntArray(IntArray const &other)
{
copy(other);
}

// destructor
IntArray::~IntArray()
{
delete [] data;
}

// overloaded assignment
IntArray const &IntArray::eek:perator=(IntArray const &other)
{
// take action only when no auto-assignment
if (this != &other)
{
delete [] data;
copy(other);
}
return (*this);
}

// copy() primitive
void IntArray::copy(IntArray const &other)
{
// set size
size = other.size;

// create array
data = new int [size];

// copy other's values
for (register int i = 0; i < size; i++)
data = other.data;
}

// here is the overloaded array operator
int &IntArray::eek:perator[](int index)
{

// check for array boundary over/underflow
if (index < 0 || index >= size)
{
cout << "IntArray: boundary overflow or underflow, index =
"
<< index << ", should range from 0 to " << size - 1 <<
endl;
exit(1);
}
return (data[index]); // emit the reference
}

int main()
{
IntArray x(20); // 20 ints //statement 1

for (int i = 0; i < 20; i++)
x = i * 2; // assign the elements

// produces boundary
// overflow
for (int i = 0; i <= 20; i++)
cout << "At index " << i << ": value is " << x << endl;

return (0);
}
///////////////////////////////////////////////////////////////////////////////////////

With Warm Regards,
Murali.




It is not clear what you want at all. Given

IntArray x(20);


and

IntArray *px = new IntArray(20);

you can't possibly have, say, x[0] and px[0] both produce data[0]. px[0]
will always use the built-in subscript operator. There is no way to avoid
it. This means that px[0] will produce the first IntArray object pointed to,
not the first element inside IntArray, data[0].

With your current code, you can have x[0] and (*px)[0] produce data[0].

Another strategy is to use a reference to a dynamically allocated object.
Note that in this case you must delete the address of the reference, e.g.,

int main()
{
// dereference pointer returned by new and assign to reference
IntArray & rx = *new IntArray(20);

for (int i = 0; i < 20; i++)
rx = i * 2; // assign the elements

// produces boundary
// overflow
for (int i = 0; i <= 20; i++)
cout << "At index " << i << ": value is " << rx << endl;

delete &rx; // take address of reference to delete

return (0);
}

You might prefer to have both a pointer and a reference variable, allowing
you to delete the straight pointer:

int main()
{
IntArray * px = new IntArray(20);
IntArray & rx = *px;

for (int i = 0; i < 20; i++)
rx = i * 2; // assign the elements

// produces boundary
// overflow
for (int i = 0; i <= 20; i++)
cout << "At index " << i << ": value is " << rx << endl;

delete px; // delete the pointer in the usual way

return (0);
}

Another possibility is to define a special type of smart pointer to hold the
address of the dynamically allocated object. You could then overload the
operator[] of this smart pointer to produce the desired effect. I would
generally recommend against this, however, since the smart pointer would
then be behaving in a way that is very unusual, which could lead to bugs.
 
N

Noah Roberts

md said:
Hi,
the following code is working for static objects.
ie the statement IntArray x(20);
my problem is i want to use this overloading operator [] for
dynamically created objects
for example the statement IntArray *x;

You would need a "smart pointer" that forwarded the message.

class ptr
{
X * x;
public:
operator[](int i) { return (*x); }
};


However, this is not a good idea as it creeps away from the norm. You
should design your interfaces to behave like someone expects...nobody
would expect the above.
 

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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top