Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > operator = overloading...

Reply
Thread Tools

operator = overloading...

 
 
Rahul
Guest
Posts: n/a
 
      12-20-2007
Hi Everyone,

I was overloading the operator= function as a class member function,

#include <iostream.h>

class A
{
int value;
public : A& operator = (const A& ref)
{
this->value = ref.value;
cout<<"in"<<endl;
return *this;
}
A(int value) : value(value)
{
}
A(const A& copy)
{
this->value = copy.value;
cout<<"copy with a value of "<<copy.value<<endl;
}
void print()
{
cout<<"value is"<<value<<endl;
}
};

int main()
{
A obj(0);
A obj1(10);
A obj2(20);
obj.print();
obj1.print();
obj2.print();
obj1 = obj = obj2;
obj.print();
obj.print();
obj2.print();
}

It works fine and all objects have a value of 20 as expected...

Next i changed the return type of the operator = function, like
so that it returns an object instead of a reference...

A operator = (const A& ref)
{
this->value = ref.value;
cout<<"in"<<endl;
return *this;
}

And as the object is returned by value, each call to operator= also
invokes the copy constructor for the temp object, which is again
passed to the operator= function, and the end result happens to be
same as with operator= function which returns a reference.

Is there any thumb rule while overloading operators, when we have
alternative implementations?

Thanks in advance!!!
 
Reply With Quote
 
 
 
 
Craig Scott
Guest
Posts: n/a
 
      12-20-2007
On Dec 20, 6:43 pm, Rahul <(E-Mail Removed)> wrote:
> Is there any thumb rule while overloading operators, when we have
> alternative implementations?


Yes. Member operators are generally expected to return a reference to
themselves (at least, that's my undestanding). This provides the
expected behaviour when chaining operators. For example:

MyClass a, b, c;
// Presumably do stuff with c here, then.....
a = b = c;

No extra copies are involved when operator=() returns by reference.

--
Computational Modeling, CSIRO (CMIS)
Melbourne, Australia

Why do you want to return by value from operator=()?
 
Reply With Quote
 
 
 
 
Rahul
Guest
Posts: n/a
 
      12-20-2007
On Dec 20, 1:52 pm, Craig Scott <(E-Mail Removed)> wrote:
> On Dec 20, 6:43 pm, Rahul <(E-Mail Removed)> wrote:
>
> > Is there any thumb rule while overloading operators, when we have
> > alternative implementations?

>
> Yes. Member operators are generally expected to return a reference to
> themselves (at least, that's my undestanding). This provides the
> expected behaviour when chaining operators. For example:
>
> MyClass a, b, c;
> // Presumably do stuff with c here, then.....
> a = b = c;
>
> No extra copies are involved when operator=() returns by reference.
>
> --
> Computational Modeling, CSIRO (CMIS)
> Melbourne, Australia
>
> Why do you want to return by value from operator=()?


But the chaining works even when operator= returns a copy too...
 
Reply With Quote
 
Kira Yamato
Guest
Posts: n/a
 
      12-20-2007
On 2007-12-20 02:43:29 -0500, Rahul <(E-Mail Removed)> said:

> Hi Everyone,
>
> I was overloading the operator= function as a class member function,
>
> #include <iostream.h>
>
> class A
> {
> int value;
> public : A& operator = (const A& ref)
> {
> this->value = ref.value;
> cout<<"in"<<endl;
> return *this;
> }
> A(int value) : value(value)
> {
> }
> A(const A& copy)
> {
> this->value = copy.value;
> cout<<"copy with a value of "<<copy.value<<endl;
> }
> void print()
> {
> cout<<"value is"<<value<<endl;
> }
> };
>
> int main()
> {
> A obj(0);
> A obj1(10);
> A obj2(20);
> obj.print();
> obj1.print();
> obj2.print();
> obj1 = obj = obj2;
> obj.print();
> obj.print();
> obj2.print();
> }
>
> It works fine and all objects have a value of 20 as expected...
>
> Next i changed the return type of the operator = function, like
> so that it returns an object instead of a reference...
>
> A operator = (const A& ref)
> {
> this->value = ref.value;
> cout<<"in"<<endl;
> return *this;
> }
>
> And as the object is returned by value, each call to operator= also
> invokes the copy constructor for the temp object, which is again
> passed to the operator= function, and the end result happens to be
> same as with operator= function which returns a reference.
>
> Is there any thumb rule while overloading operators, when we have
> alternative implementations?
>
> Thanks in advance!!!


I can't see any legitimate situation where you would prefer to return a
value instead of a reference here.

So, I would say, between those two options, always choose return by
reference since it avoids a copy constructor invocation.

--

-kira

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      12-20-2007
On Dec 20, 10:40 am, Kira Yamato <(E-Mail Removed)> wrote:
> On 2007-12-20 02:43:29 -0500, Rahul <(E-Mail Removed)> said:


[...]
> > Is there any thumb rule while overloading operators, when we
> > have alternative implementations?


> > Thanks in advance!!!


> I can't see any legitimate situation where you would prefer to
> return a value instead of a reference here.


> So, I would say, between those two options, always choose
> return by reference since it avoids a copy constructor
> invocation.


The general rule is to be as much like the built-in operators as
possible. This basically means that if the built-in operator is
an lvalue, return a reference, and if it is not, return a value.
Since = (and all of the <op>=) are lvalues, you return a
reference.

Note too that if there are implicit conversions to the data
type, you probably want the operators which don't require an
lvalue to be non-members.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
Kira Yamato
Guest
Posts: n/a
 
      12-20-2007
On 2007-12-20 04:49:53 -0500, James Kanze <(E-Mail Removed)> said:

> On Dec 20, 10:40 am, Kira Yamato <(E-Mail Removed)> wrote:
>> On 2007-12-20 02:43:29 -0500, Rahul <(E-Mail Removed)> said:

>
> [...]
>>> Is there any thumb rule while overloading operators, when we
>>> have alternative implementations?

>
>>> Thanks in advance!!!

>
>> I can't see any legitimate situation where you would prefer to
>> return a value instead of a reference here.

>
>> So, I would say, between those two options, always choose
>> return by reference since it avoids a copy constructor
>> invocation.

>
> The general rule is to be as much like the built-in operators as
> possible. This basically means that if the built-in operator is
> an lvalue, return a reference, and if it is not, return a value.
> Since = (and all of the <op>=) are lvalues, you return a
> reference.
>
> Note too that if there are implicit conversions to the data
> type, you probably want the operators which don't require an
> lvalue to be non-members.


Can a temporary object be an lvalue? The following code compiles fine
under g++ 4.0.1:

int main()
{
class T {};
T() = T();
return 0;
}

--

-kira

 
Reply With Quote
 
siddhu
Guest
Posts: n/a
 
      12-20-2007
On Dec 20, 5:53 am, Kira Yamato <(E-Mail Removed)> wrote:
> On 2007-12-20 04:49:53 -0500, James Kanze <(E-Mail Removed)> said:
>
>
>
>
>
> > On Dec 20, 10:40 am, Kira Yamato <(E-Mail Removed)> wrote:
> >> On 2007-12-20 02:43:29 -0500, Rahul <(E-Mail Removed)> said:

>
> > [...]
> >>> Is there any thumb rule while overloading operators, when we
> >>> have alternative implementations?

>
> >>> Thanks in advance!!!

>
> >> I can't see any legitimate situation where you would prefer to
> >> return a value instead of a reference here.

>
> >> So, I would say, between those two options, always choose
> >> return by reference since it avoids a copy constructor
> >> invocation.

>
> > The general rule is to be as much like the built-in operators as
> > possible. This basically means that if the built-in operator is
> > an lvalue, return a reference, and if it is not, return a value.
> > Since = (and all of the <op>=) are lvalues, you return a
> > reference.

>
> > Note too that if there are implicit conversions to the data
> > type, you probably want the operators which don't require an
> > lvalue to be non-members.

>
> Can a temporary object be an lvalue? The following code compiles fine
> under g++ 4.0.1:
>
> int main()
> {
> class T {};
> T() = T();
> return 0;
>
> }
>
> --
>
> -kira- Hide quoted text -
>
> - Show quoted text -


For user defined types temporaries can be lvalue. But its useless. So
whenever you return by value ,try to return it as const value in order
to make it consistent with POD types.

I have a question.

obj = obj1 = obj2;

In the above statement what is the order of calling of assignment
operators? I think standard does not specify any order. please
clarify.
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      12-20-2007
siddhu wrote:
> [..]
> I have a question.
>
> obj = obj1 = obj2;
>
> In the above statement what is the order of calling of assignment
> operators? I think standard does not specify any order. please
> clarify.


Yes, it does. Associativity of assignment operators is right-to-left.
That means the expression is evaluated as if it is written as

obj = (obj1 = obj2);

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
siddhu
Guest
Posts: n/a
 
      12-20-2007
On Dec 20, 10:38 am, "Victor Bazarov" <(E-Mail Removed)> wrote:
> siddhu wrote:
> > [..]
> > I have a question.

>
> > obj = obj1 = obj2;

>
> > In the above statement what is the order of calling of assignment
> > operators? I think standard does not specify any order. please
> > clarify.

>
> Yes, it does. Associativity of assignment operators is right-to-left.
> That means the expression is evaluated as if it is written as
>
> obj = (obj1 = obj2);

So how does chaining come into play?
>
> V
> --
> Please remove capital 'A's when replying by e-mail
> I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
Rahul
Guest
Posts: n/a
 
      12-20-2007
On Dec 20, 8:53 pm, siddhu <(E-Mail Removed)> wrote:
> On Dec 20, 10:38 am, "Victor Bazarov" <(E-Mail Removed)> wrote:> siddhu wrote:
> > > [..]
> > > I have a question.

>
> > > obj = obj1 = obj2;

>
> > > In the above statement what is the order of calling of assignment
> > > operators? I think standard does not specify any order. please
> > > clarify.

>
> > Yes, it does. Associativity of assignment operators is right-to-left.
> > That means the expression is evaluated as if it is written as

>
> > obj = (obj1 = obj2);

>
> So how does chaining come into play?
>
>
>
> > V
> > --
> > Please remove capital 'A's when replying by e-mail
> > I do not respond to top-posted replies, please don't ask


It is as good as saying,
obj.operator=(obj1.operator=(obj2))
 
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
T::operator int () const ambiguous with T::operator Handle () const? Tim Clacy C++ 15 05-30-2005 02:14 AM
Member operators operator>>() and operator<<() Alex Vinokur C++ 3 03-20-2005 03:11 PM
operator*(Foo) and operator*(int) const: ISO C++ says that these are ambiguous: Alex Vinokur C++ 4 11-26-2004 11:46 PM
Operator overloading on "default" operator John Smith C++ 2 10-06-2004 10:22 AM
Q: operator void* or operator bool? Jakob Bieling C++ 2 03-05-2004 04:27 PM



Advertisments