FAQ 23.05 Why do subscript operators usually come in pairs?

They usually occur in pairs so that users can access elements of a const object.

Classes that have a subscript operator often have a pair of subscript operators: a const version and a non-const version. The const version normally returns the element by value or by const reference, and the non-const version normally returns the element by non-const reference. The code for the two versions is normally quite similar if not identical.

For example, the following class has two subscript operators. It represents an Array of Fred objects. Class out_of_range is the standard exception class that is thrown if an argument is out of bounds.

 #include <stdexcept> using namespace std; class Fred { }; class Array { public:   Fred&       operator[] (unsigned i)       throw(out_of_range);   const Fred& operator[] (unsigned i) const throw(out_of_range); protected:   enum { capacity_ = 100 };   Fred data_[capacity_]; }; Fred& Array::operator[] (unsigned i) throw(out_of_range) {   if (i >= capacity_) throw out_of_range("Array::operator[]");   return data_[i]; } const Fred& Array::operator[] (unsigned i) const throw(out_of_range) {   if (i >= capacity_) throw out_of_range("Array::operator[] const");   return data_[i]; } 

When a user accesses an element of an Array via a reference-to-non-const (for example, via Array& a; see a[3] in the following code), the compiler generates a call to the non-const subscript operator. Similarly, when a user accesses an element of an Array via a reference-to-const (for example, via const Array& b; see b[3] below), the compiler generates a call to the const subscript operator. Since the non-const subscript operator returns the element by non-const reference, things like a[3] can appear on the left side of an assignment operator. Conversely, since the const subscript operator returns the element by const reference, things like b[3] cannot appear on the left side of an assignment operator:

 void sample(Array& a, const Array& b) {   Fred x, y;   x = a[3];                                          <-- 1   a[3] = y;                                          <-- 2   x = b[3];                                          <-- 3   #ifdef GENERATE_ERROR     b[3] = y;                                        <-- 4   #endif } int main() {   Array a, b;   sample(a, b); } 

(1) OK: Get a[3]

(2) OK: Change a[3]

(3) OK: Get b[3]

(4) Error: b[3] cannot be changed



C++ FAQs
C Programming FAQs: Frequently Asked Questions
ISBN: 0201845199
EAN: 2147483647
Year: 2005
Pages: 566
Authors: Steve Summit

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net