У меня есть некоторые сомнения, читая этот абзац из книги «Beginning Visual C++ 2013»:
Когда вы выражаете оставшуюся операцию присваивания как явный вызов перегруженной функции, это в конечном итоге становится:
(motto1.operator=(motto2)).operator=(motto3);
Теперь у вас есть ситуация, когда объект, возвращаемый функцией
operator=()
, используется для вызова функцииoperator=()
. Если тип возвращаемого значения простоCMessage
, это будет недопустимо, поскольку возвращается временная копия исходного объекта, которое будет значением r, а компилятор не разрешит вызов функции-члена с использованием Rvalue. Единственный способ гарантировать, что это скомпилируется и будет работать правильно, — вернуть ссылку, которая является lvalue.
Класс CMessage
определяется следующим образом:
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;
}
};
вместе с функцией main
, определенной как:
int main()
{
CMessage motto1, motto2;
CMessage motto3("A miss is as good as a mile.");
(motto1 = motto2) = motto3;
motto1.ShowIt();
motto2.ShowIt();
motto3.ShowIt();
}
Вопрос: действительно ли операторная функция возвращает rvalue или книга просто ошибается в этом утверждении?
Насколько я понимаю, код ошибочен, потому что в конечном результате motto1
не будет изменено, но в остальном это совершенно законно, потому что возвращаемая копия (включая конструктор копирования) является lvalue.