|
Page 3 of 6 const Return Values We saw in the above example the methods cWidget() where our type had a const prepended. In that position in the value that is returned may not be modified. Consider (using the above class): int main() { Foo f;
Widget *w1 = f.widget(); // fine
Widget *w2 = f.cWidget(); // ERROR - "cWidget()" // returns a const value // and "w2" is not const
const Widget *w3 = f.cWidget(); // fine
return 0; } So, if we are using a method with a const return value we must assign the value to a const local variable. If such a const return value is a pointer or a reference to a class then we cannot call non-const methods on that pointer or reference since that would break our agreement not to change it. Note: As a general rule methods should be const except when it's not possible to make them such. While getting used to the semantics you can use the compiler to inform you when a method may not be const -- it will give an error if you declare a method const that needs to be non-const. const Function Arguments The keyword const can also be used as a guarantee that a function will not modify a value that is passed in. This is really only useful for references and pointers (and not things passed by value), though there's nothing syntactically to prevent the use of const for arguments passed by value. Take for example the following fuctions: void foo( const std::string &s ) { s.append("blah"); // ERROR -- we can't modify the string
std::cout << s.length() << std::endl; // fine }
void bar( const Widget *w ) { w->rotate(); // ERROR - rotate wouldn't be const
std::cout << w->name() << std::endl; // fine } In the first example we tried to call a non-const method -- append() -- on an argument passed as a const reference, thus breaking our agreement with the caller not to modify it and the compiler will give us an error. The same is true with rotate(), but with a const pointer in the second example.
|