Reputation: 37914
I have some doubt, reading this paragraph from the "Beginning Visual C++ 2013" book:
When you express the remaining assignment operation as the explicit overloaded function call, this ultimately becomes:
(motto1.operator=(motto2)).operator=(motto3);
Now, you have a situation where the object returned from the
operator=()
function is used to call theoperator=()
function. If the return type is justCMessage
, this will not be legal because a temporary copy of the original object is returned which will be an rvalue, and the compiler will not allow a member function call using an rvalue. The only way to ensure this will compile and work correctly is to return a reference, which is an lvalue.
The class CMessage
is defined as follows:
class CMessage
{
private:
char* pmessage;
public:
void ShowIt() const
{
cout << endl << pmessage;
}
CMessage(const char* text = "Default message")
{
cout << endl << "Constructor called.";
pmessage = new char[strlen(text) + 1];
strcpy(pmessage, text);
}
CMessage(const CMessage& initM)
{
cout << "Copy constructor called" << endl;
pmessage = new char[strlen(initM.pmessage) + 1];
strcpy(pmessage, initM.pmessage);
}
~CMessage()
{
cout << "Destructor called." << endl;
delete[] pmessage;
}
CMessage operator=(const CMessage& aMess)
{
delete[] pmessage;
pmessage = new char[strlen(aMess.pmessage) + 1];
strcpy(this->pmessage, aMess.pmessage);
return *this;
}
};
along with main
function defined as:
int main()
{
CMessage motto1, motto2;
CMessage motto3("A miss is as good as a mile.");
(motto1 = motto2) = motto3;
motto1.ShowIt();
motto2.ShowIt();
motto3.ShowIt();
}
Question: Does operator function really returns an rvalue or the book is simpy wrong about that statement?
My understanding is that code is flawed, because in final result, motto1
wouldn't be changed, but other than that it is perfectly legal, because returned copy (involving a copy constructor) is a lvalue.
Upvotes: 0
Views: 77
Reputation: 238311
Does operator function really returns an rvalue or the book is simpy wrong about that statement?
Yes, this particular overloaded operator does return a value, so the value category of the call expression is a (p)rvalue. The book is correct about that.
My understanding is that code is flawed, because in final result, motto1 wouldn't be changed
If the intention is to assign motto3
to motto1
, then yes, the code is indeed flawed. However, the reason that the book gives:
compiler will not allow a member function call using an rvalue
Is not true. It is true for c, and possibly for pre-standard versions of c++, but not true for standard c++.
Upvotes: 1
Reputation: 141554
CMessage operator=(const CMessage& aMess)
returns by value. This means that a temporary object is returned and the value category of (motto1 = motto2)
is prvalue. Note that nothing is special about operator=
here, it would be the same for any function returning by value.
My understanding is that code is flawed, because in final result, motto1 wouldn't be changed, but other than that it is perfectly legal,
In ISO C++ that is true...
because returned copy (involving a copy constructor) is a lvalue.
The returned copy is a temporary object. The word "lvalue" is a value category of expressions; it is not an adjective that applies to objects. The value category of an expression consisting of a function call where that function returns by value, is prvalue, not lvalue.
compiler will not allow a member function call using an rvalue.
In ISO C++ it is fine to call a member function on an rvalue. I can't speak to Visual C++ 2013.
Upvotes: 3