Каноническая форма оператора += для классов
-
22-08-2019 - |
Вопрос
Я знаю, что это хорошая идея — сделать как можно большую часть интерфейса класса, не являющегося членом, не другом, и я только что понял, что для моего трехмерного векторного класса «Вектор3» я могу переместить +=, Операторы -= и т. д. выходят за пределы класса, оставляя только конструкторы и оператор присваивания копирования.
Вопрос в том:как должен выглядеть этот оператор?Я видел канонические формы множества других операторов и следовал их советам, но я не видел канонических форм этих операторов.Ниже я дал то, что, по моему мнению, должно быть.
Второстепенный вопрос:как эти операторы вообще называются?Арифметические операторы присваивания?
(Соответствующий) код перед:
class Vector3 {
public:
Vector3& operator+=(const Vector3& rhs);
float x, y, z;
};
Vector3& Vector3::operator+=(const Vector3 &rhs) {
x += rhs.x;
y += rhs.y;
z += rhs.z;
return *this;
}
Что я изменил на данный момент:
class Vector3 {
public:
float x, y, z;
};
Vector3& operator+=(Vector3& lhs, const Vector3& rhs) {
lhs.x += rhs.x;
lhs.y += rhs.y;
lhs.z += rhs.z;
return lhs;
}
Решение
То, что у вас есть, мне кажется хорошим.
Кстати, оператор+ обычно реализуется с помощью +=.(создайте копию lhs, а затем вызовите lhs += rhs и верните результат)
Не знаю, знаете ли вы об этом трюке, но поскольку вас беспокоят канонические способы реализации этих операторов, упомянуть об этом не помешает.:)
Другие советы
То, что у вас есть, выглядит хорошо.
Интуитивно основной способ думать об этом — это подумать о том, как бы вы хотели, чтобы код выглядел, когда вы его пишете.Если в этом случае можно написать
Vector v, w;
v += w;
w += v;
и так далее, вы на правильном пути.
Есть много хороших практических правил, которые могут помочь;видеть эта запись в FAQ по C++ есть много информации об этом.
Я бы не сказал «как можно больше интерфейса».Не так уж много можно получить, сделав operator+=
, operator-=
и т. д.не друг, не член.
Некоторые люди предпочитают делать каждую возможную функцию не-членом и не-дружественной функцией, чтобы не поддаться искушению использовать закрытые переменные-члены.Но ты взрослый человек:вы можете написать функцию как открытый член и не использовать частные переменные-члены.Я предпочитаю знать, что функция привязана к классу, и если сделать ее открытым членом, она станет явной.
В сторону примечание:
Лично я считаю, что часто можно использовать частные члены вместо общедоступных методов доступа (я знаю — я буду гореть в аду).Не всегда!-- но часто.
На самом деле, есть несколько случаев, когда вы не можете переключиться на общедоступные средства доступа за несколько минут, если решите, что вам это нужно.Но я признаю, что это непопулярная точка зрения, и я не призываю людей следовать этой философии.
Есть конкретные причины сделать уверенность функции и операторы «не друг, не член».Например, оператор<<() при использовании в качестве «оператора вставки в поток». не могу стать членом, потому что вам придется изменить класс lhs (поток).