I thought I'd try beefing up my C++ and OpenGL by looking at the recently-released Doom 3 source. Much learned so far, but I've hit a wall. The class detailed here has methods
float operator[] (int index) const
and
float & operator[] (int index)
whose bodies both read
return ( &x )[ index ];
where x
is one of the class' two data members (the other being y
; this class is for 2-vectors).
While I can understand the syntax of each version's header/prototype, I don't get why they're both present.
const
seems to appear (or not appear, as preferred) only to distinguish the headers sufficiently to allow compilation. (That is, remove const
and VS2010 refuses to compile, similarly if both headers end in const
.)
And why return a ref to a float? None of the class' seven other float-type methods do this, so I'm guessing efficiency isn't a factor (tho' maybe this operator's called vastly more often than the others).
Appreciate any insight as to what's going on here...
This is a common idiom (known as "const overloading"). See the C++ FAQ: http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.12 .
The ambiguity is resolved by whether *this
is const
or not. On a const
object, the const
overload is called, in which case it acts in a read-only style. On a non- const
object, the non- const
is called, in which case it acts in a read/write style.
Note, crucially, that this is not a way of distinguishing between read and write accesses.
Think of them as a related pair of getter and setter methods for subscripted elements. The float & operator[](int index)
is the setter version and allows you to use syntax like so:
theObject[anIndex] = 1.0;
This requires that theObject
is available to you as a non- const
object (or through an Object *
or Object &
).
In the case without const, you are using a reference because you want to change the value when calling the function. Eg setting a value: a[11] = 5.0;
The case with const is added because other functions can only be declared as const functions if all other functions that they call are also const functions.
And why return a ref to a float?
The reason to return a reference to a float is to allow the caller to modify that float. (By the way, efficiency wouldn't be a reason for this, since pointers tend to be at least as big as floats, so the extra indirection is pure cost.)
const
at the end of a method signature indicates that it can safely be called on a const
object/reference/expression. So, if v
is an idVec2
, then v[0]
may be used as an lvalue (and v[0] = 3.0f
will actually set v[0]
), but if v
is a const idVec2
, then v[0]
can only be used as an rvalue (meaning that v[0] = 3.0f
is ilegal).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.