Каноническая форма оператора + = для классов - PullRequest
4 голосов
/ 17 мая 2009

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

2 голосов
/ 17 мая 2009

То, что у тебя есть, хорошо для меня выглядит.

Кстати, когда вы приходите к оператору +, это обычно реализуется в терминах + =. (создайте копию lhs, а затем вызовите lhs + = rhs и верните результат)

Не знаю, знаете ли вы уже об этой уловке, но, поскольку вы беспокоитесь о канонических способах реализации этих операторов, не помешает упомянуть об этом. :)

1 голос
/ 17 мая 2009

Что у тебя хорошо выглядит.

Основной способ думать об этом, интуитивно, это думать о том, как бы вы хотели, чтобы код выглядел при написании. Если в этом случае вы можете написать

Vector v, w;

v += w;
w += v;

и так далее, вы на правильном пути.

Есть много хороших эмпирических правил, чтобы помочь; см. эту запись в C ++ FAQ для получения информации о ней.

0 голосов
/ 17 мая 2009

Я бы не сказал "как можно больше интерфейса". Ничего не получится, если сделать operator+=, operator-= и т. Д. Не-не-членом.

Некоторые люди предпочитают делать каждую функцию возможной, не являющейся членом, не являющейся другом, чтобы противостоять соблазну использования закрытых переменных-членов. Но вы взрослый человек: вы можете написать функцию как открытый член и не использовать переменные закрытого члена. Я предпочитаю знать, что функция привязана к классу, и, сделав ее открытым членом, она становится явной.

Примечание в сторону:
Лично я нахожу, что часто нормально использовать закрытые члены вместо общедоступных (я знаю - я буду гореть в аду). Не всегда! - но часто.
Фактически, есть несколько случаев, когда вы не смогли бы переключиться на общедоступные средства доступа в течение нескольких минут, если решили, что вам это нужно. Но я признаю, что это не популярное мнение, и я не прошу людей следовать этой философии.

Существуют конкретные причины для того, чтобы сделать определенные функции и операторы "не-другом, не-членом". Например, оператор << () при использовании в качестве «оператора вставки потока» <em>не может быть членом, поскольку вам придется изменить класс lhs (поток).

...