Каноническая форма оператора += для классов

Я знаю, что это хорошая идея, чтобы сделать как можно больше интерфейсов класса, не являющегося членом, не друга, и я только что понял, что для моего векторного 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 (поток).

Другие вопросы по тегам