|
STL iterators are modeled on pointers, so an iterator acts much like a T* pointer. Declaring an iterator const is like declaring a pointer const (i.e., declaring a T* const pointer): the iterator isn’t allowed to point to something different, but the thing it points to may be modified. If you want an iterator that points to something that can’t be modified (i.e., the STL analogue of a const T* pointer), you want a const_iterator: - std::vector vec;
- ...
- const std::vector::iterator iter =
vec.begin(); *iter = 10; ++iter; std::vector::const_iterator cIter = vec.begin(); *cIter = 10; ++cIter;
Some of the most powerful uses of const stem from its application to function declarations. Within a function declaration, const can refer to the function’s return value, to individual parameters, and, for member functions, to the function as a whole.
Having a function return a constant value often makes it possible to reduce the incidence of client errors without giving up safety or efficiency. For example, consider the declaration of the operator* function for rational numbers that is explored in Item 24: - class Rational { ... };
- const Rational operator*(const Rational& lhs, const Rational& rhs);
Many programmers squint when they first see this. Why should theresult of operator* be a const object Because if it weren’t, clientswould be able to commit atrocities like this: - Rational a, b, c;
- ...
- (a * b) = c;
-
I don’t know why any programmer would want to make an assignment to the product of two numbers, but I do know that many programmers have tried to do it without wanting to. All it takes is a simple typo (and a type that can be implicitly converted to bool): - if (a * b = c) ...
现代编译器都会提醒你,这里有可能应该写“==”而不是“=”。如果你确信你需要“=”,而不是“==”,可以再加一层括号来避免编译器的问责。
|