Источник в Doom 3: почему класс, представляющий 2-векторы, дважды перегружает оператор индекса? - PullRequest
0 голосов
/ 14 января 2012

Я подумал, что попробую улучшить свои C ++ и OpenGL, взглянув на недавно выпущенный исходник Doom 3. До сих пор многому научился, но я врезался в стену. Класс подробный здесь имеет методы

float  operator[] (int index) const  

и

float &  operator[] (int index) 

чьи тела читают

return ( &x )[ index ];

где x - это один из двух элементов данных класса (другой является y; этот класс для 2-векторов).

Хотя я могу понять синтаксис заголовка / прототипа каждой версии, я не понимаю, почему они оба присутствуют.

const, кажется, появляется (или не появляется, как предпочитается) только для того, чтобы различать заголовки в достаточной степени, чтобы позволить компиляцию. (То есть, удалить const и VS2010 отказывается компилировать, аналогично, если оба заголовка заканчиваются на const.)

А зачем возвращать ссылку на поплавок? Ни один из семи других методов класса не делает этого, поэтому я предполагаю, что эффективность не имеет значения (хотя, может быть, этот оператор вызывается гораздо чаще, чем другие).

Ценю любое понимание того, что здесь происходит ...

Ответы [ 4 ]

7 голосов
/ 14 января 2012

Это распространенная идиома (известная как «перегрузка констант»).См. C ++ FAQ: http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.12.

Неоднозначность определяется тем, является ли *this const или нет.Для объекта const вызывается перегрузка const, и в этом случае он действует только для чтения.Для не const объекта вызывается не const, и в этом случае он действует в стиле чтения / записи.

Важно отметить, что это не способ различения доступа для чтения и записи.

1 голос
/ 14 января 2012

Думайте о них как о связанной паре методов getter и setter для подписанных элементов.float & operator[](int index) является версией setter и позволяет использовать синтаксис следующим образом:

theObject[anIndex] = 1.0;

Для этого необходимо, чтобы theObject был доступен для вас как объект, не являющийся const(или через Object * или Object &).

0 голосов
/ 14 января 2012

А зачем возвращать ссылку на поплавок?

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

const в конце подписи метода указывает, что он может безопасно вызываться для const объекта / ссылки / выражения. Так, если v является idVec2, тогда v[0] может использоваться как lvalue (и v[0] = 3.0f фактически установит v[0]), но если v является const idVec2, то v[0] может использоваться только в качестве значения r (это означает, что v[0] = 3.0f нелегально).

0 голосов
/ 14 января 2012

В случае без const вы используете ссылку, потому что вы хотите изменить значение при вызове функции.Например, установка значения: a [11] = 5.0;

Добавлен регистр с const, поскольку другие функции могут быть объявлены как const-функции, только если все остальные функции, которые они вызывают, также являются константными функциями.

...