|
Page 2 of 6 The const Keyword There is a lot of confusion about the use of const. I'll try to cover the basic syntax and the places where it is appropriate. const Variables Either local or class-level variables may be declared const indicating that you don't intend to change their value after they're initialized. const local variables are often used in conjunction with const return values, which will be discussed below. For example: int main() { const int i = 10;
i = 3; // ERROR - we can't change "i"
int &j = i; // ERROR - we promised not to // change "i" so we can't // create a non-const reference // to it
const int &x = i; // fine - "x" is a reference // to "i"
return 0; } const Methods Const methods are a way for us to say that a method does not modify the member variables of a class. It's a hint both to the programmer and the compiler that a given method doesn't change the internal state of a class. Take for example: class Foo { public: int value() const { return m_value; }
void setValue( int i ) { m_value = i; }
private: int m_value; }; Here value() clearly does not change m_value and as such can and should be const. However setValue() does modify m_value and as such cannot be const. Another subtlety that is often missed is that by extension a const method cannot call a non-const method (and the compiler will complain if you try). Since we assume that a non-const method does modify the member variables of our class, we can't call that from a method where we've promised not to do just that. Also note the placement of the keyword in the method declaration -- it must follow the method decleration. Specifically all of the following cases are different: class Foo { public: /* * Modifies m_widget and the user * may modify the returned widget. */ Widget *widget();
/* * Does not modify m_widget but the * user may modify the returned widget. */ Widget *widget() const;
/* * Modifies m_widget, but the user * may not modify the returned widget. */ const Widget *cWidget();
/* * Does not modify m_widget and the user * may not modify the returned widget. */ const Widget *cWidget() const;
private: Widget *m_widget; } Note: Also interesting to note from the above is that while the compiler differentiates between const and non-const methods and allows overloading based on a method's const-ness, it does not differentiate between const and non-const return values -- if the last two methods had also been named widget() the compiler would have given us an error due to the ambiguous overload.
|