Каноническая форма оператора += для классов
Я знаю, что это хорошая идея, чтобы сделать как можно больше интерфейсов класса, не являющегося членом, не друга, и я только что понял, что для моего векторного 3D-класса, "Vector3", я могу переместить +=, -= и т. д. операторы вне класса, оставляя только конструкторы и оператор присваивания копии.
Вопрос в том, как должен выглядеть этот оператор. Я видел канонические формы множества других операторов и следовал их советам, но я не видел канонических форм этих операторов. Я дал то, что я думаю, должно быть ниже.
Вторичный вопрос: как эти операторы вообще называются? Арифметические операторы присваивания?
(Соответствующий) код перед:
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;
}
3 ответа
То, что у тебя есть, выглядит хорошо для меня.
Кстати, когда вы приходите к оператору +, это обычно реализуется в терминах +=. (создайте копию lhs, а затем вызовите lhs += rhs и верните результат)
Не знаю, знаете ли вы уже об этом трюке, но, поскольку вы беспокоитесь о канонических способах реализации этих операторов, упомянуть об этом не помешает.:)
Что у тебя хорошо выглядит
Основной способ думать об этом, интуитивно, это думать о том, как бы вы хотели, чтобы код выглядел при написании. Если в этом случае вы можете написать
Vector v, w;
v += w;
w += v;
и так далее, вы на правильном пути.
Есть много хороших правил, чтобы помочь; см. эту запись в C++ FAQ для многих на нем.
Я бы не сказал "как можно больше интерфейса". Там не так много, чтобы получить, делая operator+=
, operator-=
и т.д. не-не-не-друг.
Некоторые люди предпочитают делать каждую функцию возможной, не являющейся членом, не являющейся другом, чтобы противостоять искушению использовать закрытые переменные-члены. Но вы взрослый человек: вы можете написать функцию как открытый член и не использовать переменные закрытого члена. Я предпочитаю знать, что функция привязана к классу, и делая ее общедоступным, делает ее явной.
Помимо примечания:
Лично я нахожу, что часто нормально использовать закрытые члены вместо общедоступных (я знаю - я буду гореть в аду). Не всегда! - но часто.
Фактически, есть несколько случаев, когда вы не смогли бы переключиться на общедоступные средства доступа в течение нескольких минут, если решили, что вам это нужно. Но я признаю, что это не популярный взгляд, и я не прошу людей следовать этой философии.
Существуют конкретные причины делать определенные функции и операторы "не-друзьями, не-членами". Например, оператор << () при использовании в качестве "оператора вставки потока" не может быть сделан членом, поскольку вам придется изменить класс lhs (поток).