Reputation: 23095
I read that, reference is returned from a overloaded assignment operator to enable operator chaining. But without that return also, operator chaining seems to work.
Can someone shed some light on this?
class A
{
public:
int x,y;
char* str;
//Default Constructor
A(){}
//Constructor
A(int a, int b, char* s){
cout<<"initialising\n";
x = a;
y = b;
str = new char[10];
str = s;
}
//Destructor
~A(){}
//Overloaded assignment operator
const A& operator=(const A& obj)
{
cout<<"Invoking Assignment Operator\n";
x = obj.x;
y = obj.y;
str = new char[10];
str = obj.str;
//return *this;
}
};
ostream& operator<<(ostream& os, const A& obj)
{
os <<"X="<< obj.x<<" Y="<<obj.y<<" Str="<<obj.str<<"\n";
return os;
}
int main()
{
A c(3,4,"Object C");
cout<<c;
A d, e, f;
d = e = f = c; //Assignment operator invoked 3 times
cout<<e;
}
Output:
initialising
X=3 Y=4 Str=Object C
Invoking Assignment Operator
Invoking Assignment Operator
Invoking Assignment Operator
X=3 Y=4 Str=Object C
Upvotes: 0
Views: 764
Reputation: 490108
This rule originated from code something like this:
struct Foo {
Foo& copy(const Foo& x) {
return (*this = x);
}
};
At that time, two things were different about C++:
The code above was intended to be equivalent to:
*this = x;
return *this;
But, it wasn't -- since operator=
returned an rvalue, the compiler generated a temporary to hold the result of the assignment, then since the function returned a reference, it returned a reference to that temporary. Then, of course, things went badly in a hurry, because you now had a dangling reference to a temporary that was destroyed at the end of the full expression in which it was created. In short, a class case of returning a reference to a local -- except that it took quite a bit of analysis to realize that the local was being generated at all, not to mention a reference to it being returned.
If you define your operator=
to return a value instead of a reference, it's going to have to generate a temporary, just like the compiler did in the code above. I haven't thought through the rest in detail to figure out whether the other changes in the current language would be enough to protect you in a case like this, but my immediate reaction is that you're about halfway to reconstituting that ancient bug, so unless you have absolutely no choice in the matter, I'd stay well away.
Upvotes: 2
Reputation: 258568
You're running into undefined behavior because the return type expected from operator =
is const A&
and you're not returning anything.
It's just unlucky that it works for you. (yes, unlucky, because undefined behavior that appears to work is the worst)
I get a compile error in MSVS, and ideone.com runs into a runtime error.
Upvotes: 3