G
Guest
I have not posted to comp.lang.c++ (or comp.lang.c++.moderated)
before. In general when I have a C++ question I look for answers in
"The C++ Programming Language, Third Edition" by Stroustrup.
However, I've come upon a question that I can neither answer from
"The Book" or a Google search (so yes, at least I RTFBed). I'm
hoping that someone in this news group might know the answer.
Overloading the [] Operator
Say I want to develop a class that supports the overloaded []
operator and reads and writes the "int" type. I thought that the
way this was done was:
class MyClass
{
//...
// in theory, the RHS operator
const int operator[](const int i ) const;
// in theory, the LHS operator
int& operator[](const int i );
//...
}
Here RHS stands for right-hand-side, or an r-value and LHS stands
for left-hand-side, or an l-value.
MyClass foo;
int i = foo[j]; // RHS reference NOT!
foo[j] = i; // LHS reference
Much to my surprise, the first statement "i = foo[j];" seems to
invoke the overloaded operator I've labeled LHS. I tried this with
Microsoft's Visual C++ 6.0 compiler, I think upgraded with at least
service pack 5 (version 12.00.8804) and the GNU 2.95.2 g++ compiler
for Intel on freeBSD. Both compilers got the same results.
To put things in more concrete form, I've included a complete test
code below:
#include <stdio.h>
class overloaded
{
private:
int *pArray;
public:
overloaded( size_t size )
{
pArray = new int[ size ];
}
~overloaded()
{
delete [] pArray;
}
// in theory, the RHS operator
const int operator[](const int i ) const
{
printf("RHS a[%2d]\n", i );
return pArray;
}
// in theory, the LHS operator
int& operator[](const int i )
{
printf("LHS a[%2d]\n", i );
return pArray;
}
}; // overloaded
int
main()
{
const int len = 4;
overloaded a(len);
int b[len];
int i;
printf("initializing array...\n");
for (i = 0; i < len; i++) {
a = i + 1;
}
printf("reading values from array in an 'if' statement...\n");
for (i = 0; i < len; i++) {
if (a != i+1) {
printf("bad value");
break;
}
}
printf("reading values from an array in an assignment...\n");
for (i = 0; i < len; i++) {
b = a;
}
printf("expression...\n");
int j = a[1] + a[2];
return 0;
}
When I compile and execute this code I get
initializing array...
LHS a[ 0]
LHS a[ 1]
LHS a[ 2]
LHS a[ 3]
reading values from array in an 'if' statement...
LHS a[ 0]
LHS a[ 1]
LHS a[ 2]
LHS a[ 3]
reading values from an array in an assignment...
LHS a[ 0]
LHS a[ 1]
LHS a[ 2]
LHS a[ 3]
expression...
LHS a[ 1]
LHS a[ 2]
I expected that the "initialization" would reference the LHS form of
the overloaded function. However, much to my surprise, the 'if'
statement and the value reads also referenced the LHS form of the
overloaded operator. I'm surprised at this, since as far as I can
tell, this way I've implemented the overloaded [] operators is
pretty much "text book" approach.
Is there a way to implement this class so that the RHS [] will be
called when it seems to be an r-value? That is
if (a != i+1)
b = a;
int j = a[1] + a[2];
In this example the difference is not critical, since the code gets
the expected results. However, proper invokation of the RHS and LHS
operators is important in the case of reference counted objects,
which is the appliction that originally motivated this question.
I'm working on a third version of a reference counted String class,
which can be found here:
http://www.bearcave.com/software/string/index.html. This class
suffers from a bug caused by the behavior of the [] operator
described above. In particular, it is making too many copies.
I have noted Stroustrup's solution using the Cref class (from 11.12
of "The Book"). However, in his code it appears that you might as
well omit the RHS version of the [] operator.
I'd be grateful for a version of the test code above that invokes
the RHS operator for what appear to be r-value references. Could
you please copy any postings on this to "iank at bearcave dot com".
Thank you for your help,
Ian
iank at bearcave dot com
before. In general when I have a C++ question I look for answers in
"The C++ Programming Language, Third Edition" by Stroustrup.
However, I've come upon a question that I can neither answer from
"The Book" or a Google search (so yes, at least I RTFBed). I'm
hoping that someone in this news group might know the answer.
Overloading the [] Operator
Say I want to develop a class that supports the overloaded []
operator and reads and writes the "int" type. I thought that the
way this was done was:
class MyClass
{
//...
// in theory, the RHS operator
const int operator[](const int i ) const;
// in theory, the LHS operator
int& operator[](const int i );
//...
}
Here RHS stands for right-hand-side, or an r-value and LHS stands
for left-hand-side, or an l-value.
MyClass foo;
int i = foo[j]; // RHS reference NOT!
foo[j] = i; // LHS reference
Much to my surprise, the first statement "i = foo[j];" seems to
invoke the overloaded operator I've labeled LHS. I tried this with
Microsoft's Visual C++ 6.0 compiler, I think upgraded with at least
service pack 5 (version 12.00.8804) and the GNU 2.95.2 g++ compiler
for Intel on freeBSD. Both compilers got the same results.
To put things in more concrete form, I've included a complete test
code below:
#include <stdio.h>
class overloaded
{
private:
int *pArray;
public:
overloaded( size_t size )
{
pArray = new int[ size ];
}
~overloaded()
{
delete [] pArray;
}
// in theory, the RHS operator
const int operator[](const int i ) const
{
printf("RHS a[%2d]\n", i );
return pArray;
}
// in theory, the LHS operator
int& operator[](const int i )
{
printf("LHS a[%2d]\n", i );
return pArray;
}
}; // overloaded
int
main()
{
const int len = 4;
overloaded a(len);
int b[len];
int i;
printf("initializing array...\n");
for (i = 0; i < len; i++) {
a = i + 1;
}
printf("reading values from array in an 'if' statement...\n");
for (i = 0; i < len; i++) {
if (a != i+1) {
printf("bad value");
break;
}
}
printf("reading values from an array in an assignment...\n");
for (i = 0; i < len; i++) {
b = a;
}
printf("expression...\n");
int j = a[1] + a[2];
return 0;
}
When I compile and execute this code I get
initializing array...
LHS a[ 0]
LHS a[ 1]
LHS a[ 2]
LHS a[ 3]
reading values from array in an 'if' statement...
LHS a[ 0]
LHS a[ 1]
LHS a[ 2]
LHS a[ 3]
reading values from an array in an assignment...
LHS a[ 0]
LHS a[ 1]
LHS a[ 2]
LHS a[ 3]
expression...
LHS a[ 1]
LHS a[ 2]
I expected that the "initialization" would reference the LHS form of
the overloaded function. However, much to my surprise, the 'if'
statement and the value reads also referenced the LHS form of the
overloaded operator. I'm surprised at this, since as far as I can
tell, this way I've implemented the overloaded [] operators is
pretty much "text book" approach.
Is there a way to implement this class so that the RHS [] will be
called when it seems to be an r-value? That is
if (a != i+1)
b = a;
int j = a[1] + a[2];
In this example the difference is not critical, since the code gets
the expected results. However, proper invokation of the RHS and LHS
operators is important in the case of reference counted objects,
which is the appliction that originally motivated this question.
I'm working on a third version of a reference counted String class,
which can be found here:
http://www.bearcave.com/software/string/index.html. This class
suffers from a bug caused by the behavior of the [] operator
described above. In particular, it is making too many copies.
I have noted Stroustrup's solution using the Cref class (from 11.12
of "The Book"). However, in his code it appears that you might as
well omit the RHS version of the [] operator.
I'd be grateful for a version of the test code above that invokes
the RHS operator for what appear to be r-value references. Could
you please copy any postings on this to "iank at bearcave dot com".
Thank you for your help,
Ian
iank at bearcave dot com