Я только начинаю C ++. Меня немного смущает возвращаемый тип оператора присваивания и разыменования. Я следую за книгой C ++ Primer. В различных случаях автор говорит, что возвращаемый тип оператора присваивания является ссылкой на тип левого операнда, но позже он говорит, что возвращаемый тип является типом левого операнда. Я сослался на C ++ 11 Standard Sec. 5.17, где возвращаемый тип описывается как «lvalue со ссылкой на левый операнд».
Точно так же я не могу понять, возвращает ли разыменование указанный объект или ссылку на этот объект.
Эти утверждения эквивалентны? Если так, то как? Любое объяснение будет оценено.
Стандарт правильно определяет тип возврата оператора присваивания.
На самом деле, сама операция присваивания не зависит от возвращаемого значения — поэтому тип возвращаемого значения не так прост для понимания.
Тип возврата важен для операций цепочки.
Рассмотрим следующую конструкцию: a = b = c;
, Это должно быть равно a = (b = c)
т.е. c
должны быть назначены в b
а также b
в a
, Перепишите это как a.operator=(b.operator=(c))
, Для назначения в a
правильно работать тип возврата b.operator=(c)
должен быть ссылкой на внутренний результат присваивания (он также будет работать с копией, но это просто ненужные накладные расходы).
Тип возвращаемого значения оператора разыменования зависит от вашей внутренней логики, определяйте ее так, как вам нужно.
Они оба могут быть чем угодно, но обычно operator =
возвращает текущий объект по ссылке, т.е.
A& A::operator = ( ... )
{
return *this;
}
И да, «ссылка на тип левого операнда» и «lvalue в отношении левого операнда» означают одно и то же.
Оператор разыменования может иметь практически любой тип возврата. В основном это зависит от логики программы, потому что вы перегружаете оператор, который применяется к объекту, а не к указателю на объект. Обычно это используется для умных указателей или итераторов и возвращает объект, который они обертывают:
struct smart_ptr
{
T* innerPtr;
T* smart_ptr::operator* ()
{
return innerPtr;
}
}
smart_ptr p;
T* x = *p;
Я видел подобные проблемы, но я думаю, что было бы лучше использовать
X& X::operator=(const X&);
Используя это, вы сможете повторно использовать объект в цепочке присваивания.