473,406 Members | 2,549 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

index operator[] overloading

Can anyone explain how this works. How may I implement this?

I want to be able to use the operator on both lhs and rhs of assignment
statements. The rhs is a no-brainer (at least I think I got it right):

class MyArray
{
public:
MyArray(const size_t size):m_size(size){ arr_ = new double[size]; }
~MyArray(){ if (arr_) delete[] arr_ ;}

double operator[](const size_t idx)
{ if (idx < m_size)
return arr_[idx];
throw std::exception
}

private:
MyArray(const MyArray&);
operator= (const MyArray&);

double *arr_ ;
size_t m_size ;
}
I read somewhere that the type returned from the [] operator must be a
reference, but I did not quite follow the reasoning/logic - anyone care
to explain ?
May 29 '07 #1
15 17928
Bart Simpson wrote:
>
I read somewhere that the type returned from the [] operator must be a
reference, but I did not quite follow the reasoning/logic - anyone care
to explain ?
A reference is a variable that relates to another variable. for example

int x = 0;
int& y = x;
y = 1;

at the end, x will have a value of 1, because y refers to the same
memory location as x, so it's bind to the x value until the end of its
scope (that hopefully is before or at the same time as the x one :)

In your case it's exactly the same: if you return a reference, you are
returning a (temporary) variable that refers to the address of the
element that you want to modify. So, if you assign a value to this
variable (that would be prohibited if it wasn't a reference, because is
a temporary), the value will be written in the memory location of your
array element.

that's it!

Regards,

Zeppe
May 29 '07 #2
Thanks Zeppe that clarifies that.

So to implement it one has to implement BOTH of these?

myType operator[](const size_t) const;
myType& operator[](const size_t);
May 29 '07 #3
Bart Simpson wrote:
Thanks Zeppe that clarifies that.

So to implement it one has to implement BOTH of these?

myType operator[](const size_t) const;
myType& operator[](const size_t);
exactly, and the compiler will chose the proper one based on the
"const". Another hint: the method

myType operator[](const size_t) const;

makes a copy of the element that it returns, which can be undesirable if
the objects myType are big. So, it usually common to do

const myType& operator[](const size_t) const;
myType& operator[](const size_t);

if you return a const reference, you can't use it in the left side of
the assignment, and you avoid the copy on the return.

Regards,

Zeppe
May 29 '07 #4


Zeppe wrote:
Bart Simpson wrote:
>Thanks Zeppe that clarifies that.

So to implement it one has to implement BOTH of these?

myType operator[](const size_t) const;
myType& operator[](const size_t);


exactly, and the compiler will chose the proper one based on the
"const". Another hint: the method

myType operator[](const size_t) const;

makes a copy of the element that it returns, which can be undesirable if
the objects myType are big. So, it usually common to do

const myType& operator[](const size_t) const;
myType& operator[](const size_t);

if you return a const reference, you can't use it in the left side of
the assignment, and you avoid the copy on the return.

Regards,

Zeppe
Thanks!
May 29 '07 #5
On May 29, 7:30 pm, Zeppe
<zep_p@.remove.all.this.long.comment.yahoo.itwrote :
Bart Simpson wrote:
Thanks Zeppe that clarifies that.
So to implement it one has to implement BOTH of these?
myTypeoperator[](constsize_t)const;
myType&operator[](constsize_t);

exactly, and the compiler will chose the proper one based on the
"const". Another hint: the method
To the much of my surprise, I tried this and the non-constant version
is always called. Here is the code:

#include <iostream>

class MyArray
{
public:
MyArray(const size_t size) : m_size(size) {
arr_ = new double[size];
}

~MyArray() {
if (arr_) delete[] arr_ ;
}

double& operator[](const size_t idx)
{
std::cout << "LHS" << std::endl;
return arr_[idx];
}

const double& operator[](const size_t idx) const
{
std::cout << "RHS" << std::endl;
return arr_[idx];
}

double *arr_;
size_t m_size;
};

int main(int argc, char** argv) {
MyArray a(3);
a[0] = 8.0;
std::cout << a[0] << std::endl;
return 0;
}

The output in both cases is "LHS". What's wrong?

-Mustafa

May 29 '07 #6
Project X wrote:
On May 29, 7:30 pm, Zeppe
<zep_p@.remove.all.this.long.comment.yahoo.itwrote :
>Bart Simpson wrote:
>>Thanks Zeppe that clarifies that.
>>So to implement it one has to implement BOTH of these?
>>myTypeoperator[](constsize_t)const;
myType&operator[](constsize_t);

exactly, and the compiler will chose the proper one based on the
"const". Another hint: the method

To the much of my surprise, I tried this and the non-constant version
is always called. Here is the code:

#include <iostream>

class MyArray
{
public:
MyArray(const size_t size) : m_size(size) {
arr_ = new double[size];
}

~MyArray() {
if (arr_) delete[] arr_ ;
}

double& operator[](const size_t idx)
{
std::cout << "LHS" << std::endl;
return arr_[idx];
}

const double& operator[](const size_t idx) const
{
std::cout << "RHS" << std::endl;
return arr_[idx];
}

double *arr_;
size_t m_size;
};

int main(int argc, char** argv) {
MyArray a(3);
a[0] = 8.0;
std::cout << a[0] << std::endl;
return 0;
}

The output in both cases is "LHS". What's wrong?
Nothing. 'a' is declared non-const. Why would a const function
be called when non-const is available?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 29 '07 #7
On 29 Maj, 21:03, Project X <elsheik...@gmail.comwrote:
On May 29, 7:30 pm, Zeppe

<zep_p@.remove.all.this.long.comment.yahoo.itwrote :
Bart Simpson wrote:
Thanks Zeppe that clarifies that.
So to implement it one has to implement BOTH of these?
>myTypeoperator[](constsize_t)const;
myType&operator[](constsize_t);
exactly, and the compiler will chose the proper one based on the
"const". Another hint: the method

To the much of my surprise, I tried this and the non-constant version
is always called. Here is the code:

#include <iostream>

class MyArray
{
public:
MyArray(const size_t size) : m_size(size) {
arr_ = new double[size];
}

~MyArray() {
if (arr_) delete[] arr_ ;
}

double& operator[](const size_t idx)
{
std::cout << "LHS" << std::endl;
return arr_[idx];
}

const double& operator[](const size_t idx) const
{
std::cout << "RHS" << std::endl;
return arr_[idx];
}

double *arr_;
size_t m_size;

};

int main(int argc, char** argv) {
MyArray a(3);
a[0] = 8.0;
std::cout << a[0] << std::endl;
return 0;

}

The output in both cases is "LHS". What's wrong?
Your program works fine. When the compiler chooses between operator[]
(const size_t idx) and operator[](const size_t idx) const, it makes
its determination based on whether the object in question is const or
not. Since your "a" is non-const, it will always choose the non-const
operator. Try e.g. adding this function and call it:

void f_const(MyArray const& a)
{
a[0];
}

then compare it with
void f_non_const(MyArray& a)
{
a[0];
}

/Peter

May 29 '07 #8
In article <NM*********************@bt.com>, 12**********@terrace.com
says...
Thanks Zeppe that clarifies that.

So to implement it one has to implement BOTH of these?

myType operator[](const size_t) const;
myType& operator[](const size_t);
You probably need a Proxy. See _More Effective C++_, Item 30.

--
Later,
Jerry.

The universe is a figment of its own imagination.
May 30 '07 #9
On Wed, 30 May 2007 06:51:09 -0600, Jerry Coffin wrote:
In article <NM*********************@bt.com>, 12**********@terrace.com
says...
>Thanks Zeppe that clarifies that.

So to implement it one has to implement BOTH of these?

myType operator[](const size_t) const; myType& operator[](const
size_t);

You probably need a Proxy.
Why?
See _More Effective C++_, Item 30.
Um... not everyone has that book...

--
Lionel B
May 30 '07 #10
On May 30, 9:58 am, Lionel B <m...@privacy.netwrote:
On Wed, 30 May 2007 06:51:09 -0600, Jerry Coffin wrote:
In article <NMKdnXsg9qWXzsHbRVny...@bt.com>, 123evergr...@terrace.com
says...
Thanks Zeppe that clarifies that.
So to implement it one has to implement BOTH of these?
myType operator[](const size_t) const; myType& operator[](const
size_t);
You probably need a Proxy.

Why?
See _More Effective C++_, Item 30.

Um... not everyone has that book...

--
Lionel B
Buy it now! It is cheap and worthy!

May 30 '07 #11
In article <f3**********@south.jnrs.ja.net>, me@privacy.net says...

[ ... ]
myType operator[](const size_t) const; myType& operator[](const
size_t);
You probably need a Proxy.

Why?
Because it works quite nicely in this situation, and attempts at doing
the job without a proxy won't.
See _More Effective C++_, Item 30.

Um... not everyone has that book...
If they want to deal with this subject, it's worth getting. Seriously,
that item starts on page 213 and ends up page 228. That's far too much
material to attempt to reproduce in a Usenet post -- especially since
(at least if memory serves) it contains references to other parts of the
book as well, so a standalone post would need to contain still more.

Almost anybody getting beyond the basics of C++ should get (probably all
of) Scott Meyers' books -- _Effective C++_ (currently in the third
edition, I believe) is definitely the best of them, but _More Effective
C++_ and _Effective STL_ are worth getting as well. Alternatively, the
_Effective C++ CD_ delivers essentially the same content as the first
two books in electronic form for a bit less money and a lot better
searching -- besides it lets you help support "a man with hair worthy of
Kevlin Henney" (sorry, that's a little bit of a reversed, inside joke,
but if Scott or Kevlin reads this, they'll probably laugh.)

--
Later,
Jerry.

The universe is a figment of its own imagination.
May 31 '07 #12
On 2007-05-30 17:34:39 -0700, Jerry Coffin <jc*****@taeus.comsaid:
In article <f3**********@south.jnrs.ja.net>, me@privacy.net says...

[ ... ]
>>>myType operator[](const size_t) const; myType& operator[](const
size_t);

You probably need a Proxy.

Why?

Because it works quite nicely in this situation, and attempts at doing
the job without a proxy won't.
Won't work in what way?
--
Clark S. Cox III
cl*******@gmail.com

May 31 '07 #13
In article <2007053114072116807-clarkcox3@gmailcom>, cl*******@gmail.com
says...

[ ... ]
Because it works quite nicely in this situation, and attempts at doing
the job without a proxy won't.

Won't work in what way?
Won't invoke the correct version of the operator (const vs. non-const)
in the right situation -- in particular, in the right side of an
assignment, you want the const operator called, and in the left side,
you want the non-const operator called. Overloading the operators
directly, the one that gets called is based on whether the object is
const or not -- for example, if it's not const, the non-const operator
is called even on the right side of the assignment.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jun 1 '07 #14
On Thu, 31 May 2007 22:28:35 -0600, Jerry Coffin wrote:
In article <2007053114072116807-clarkcox3@gmailcom>, cl*******@gmail.com
says...

[ ... ]
Because it works quite nicely in this situation, and attempts at
doing the job without a proxy won't.

Won't work in what way?

Won't invoke the correct version of the operator (const vs. non-const)
in the right situation -- in particular, in the right side of an
assignment, you want the const operator called, and in the left side,
you want the non-const operator called.
Do I? How do you know?
Overloading the operators
directly, the one that gets called is based on whether the object is
const or not -- for example, if it's not const, the non-const operator
is called even on the right side of the assignment.
But perhaps that's what I want... ok, most of the time I probably don't,
but you can't assume that.

--
Lionel B
Jun 4 '07 #15
In article <f4**********@south.jnrs.ja.net>, me@privacy.net says...
On Thu, 31 May 2007 22:28:35 -0600, Jerry Coffin wrote:
[ ... ]
Won't invoke the correct version of the operator (const vs. non-const)
in the right situation -- in particular, in the right side of an
assignment, you want the const operator called, and in the left side,
you want the non-const operator called.

Do I? How do you know?
The same way I know that you want your operator= to return *this, that
you don't want your destructors to throw exceptions, and so on.
Overloading the operators
directly, the one that gets called is based on whether the object is
const or not -- for example, if it's not const, the non-const operator
is called even on the right side of the assignment.

But perhaps that's what I want... ok, most of the time I probably don't,
but you can't assume that.
In point of fact, experience indicates that it's quite a safe
assumption. Yes, when people overload operator[] for completely
different purposes (e.g. Boost.spirit) it's sometimes reasonable to do
things entirely differently. When you're using it for subscripting,
however, this is an "assumption" about the same way it's an
"assumption" that the sun will rise tomorrow morning.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jun 4 '07 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

16
by: gorda | last post by:
Hello, I am playing around with operator overloading and inheritence, specifically overloading the + operator in the base class and its derived class. The structure is simple: the base class...
51
by: Jojo | last post by:
Is there any way to get to the left-hand side of an operator? Consider the following (this is not meant to be perfect code, just an example of the problem): class Matrix { public: int data;...
13
by: Jon Cosby | last post by:
VB .Net does support operator overloading, doesn't it? It seems like this should overload binary addition, but VB doesn't recognize "Operator" Public Shared Operator +(ByVal c1 as cnum, ByVal c2...
2
by: vivekian | last post by:
Have a pointer to an object of class type task task * A ; Now this object takes operator overloading like A<<2 ; which assigns the number 2 to one of the members of the object A.
3
by: y-man | last post by:
Hi, I am trying to get an overloaded operator to work inside the class it works on. The situation is something like this: main.cc: #include "object.hh" #include "somefile.hh" object obj,...
22
by: clicwar | last post by:
A simple program with operator overloading and copy constructor: #include <iostream> #include <string> using namespace std; class Vector { private: float x,y; public: Vector(float u, float...
2
by: rn5a | last post by:
I use VB.NET to create ASP.NET apps. If I am not wrong, there is something called method overloading in VB.NET (like in C#) which is one of the features in OOP (polymorphism) but does VB.NET also...
8
by: Wayne Shu | last post by:
Hi everyone, I am reading B.S. 's TC++PL (special edition). When I read chapter 11 Operator Overloading, I have two questions. 1. In subsection 11.2.2 paragraph 1, B.S. wrote "In particular,...
4
by: =?ISO-8859-1?Q?Tom=E1s_=D3_h=C9ilidhe?= | last post by:
Operator overloads are just like any other member function, you can make them do whatever you want. However, of course, we might expect them to behave in a certain way. The ++ operator should...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.