2009-05-16 3 views
4

Я знаю, что это хорошая идея сделать как можно большую часть интерфейса не-члена-друга, а также я понял, что для моего класса 3D-векторов, 'Vector3', я могу переместить операторы + =, = = и т. Д. Из класса, оставив только конструкторы и оператор присваивания копий.Каноническая форма оператора + = для классов

Вопрос в том, как должен выглядеть этот оператор? Я видел канонические формы множества других операторов и следовал их советам, но я не видел канонических форм этих операторов. Я дал то, что, как я думаю, должно быть ниже.

Вопрос вторичный: что называют эти операторы? Арифметические операции присваивания?

The (необходимо) код перед:

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; 
} 
+0

Поскольку вы просили их имя: Они называются операторы составного присваивания –

ответ

2

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

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

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

+0

Справедливо, я принимаю ваш ответ, так как там у вас за две минуты до других ребят;) Я знаю об этом, но других читать это может и не так, так что спасибо за это! –

0

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

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

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

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

+0

В этом случае на самом деле существует множество функций, отличных от членов, поскольку иногда полезно выполнять преобразования по типам левого объекта, поэтому, если что-либо выглядит более аккуратно, кластеризуя все функции вне класса, а не разделяя их между членом и нечленом :) Хороший совет в целом, хотя, спасибо. –

+1

Я не согласен. Если функция или оператор не нуждается в доступе к закрытым переменным, зачем давать им доступ? Да, мы можем просто не обращаться к ним при записи функции, но что позже, когда мы отлаживаем код? Или тестирование класса? Мы должны, по крайней мере, изучить все функции-члены, чтобы убедиться, что они делают что-то неприятное для частных членов. Поэтому, если у вас есть опция, почему бы не оставить оператор + = чисто вне класса? Где стоимость? – jalf

+0

@jalf: да, я с тобой. В целом; действительно, я обещаю. Я помедлил, разместив это. Но - позвольте мне шокировать моих друзей и коллег - иногда я могу быть прагматичным: эти операторы обычно имеют три лайнера, классы, которые используют их, как правило, являются «типами ценностей», там, как правило, полдюжины из них, и они, как правило, довольно тривиальны. Тогда на практике это просто не имеет значения. Я скорее сосредоточусь на методах страницы плюс. –

1

Что у вас хорошо выглядит.

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

Vector v, w; 

v += w; 
w += v; 

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

Есть много хороших правил, которые помогут вам; см. this entry в C++ FAQ для лотов на нем.