In Effective C++
Item 03, Use const whenever possible.
class Bigint { int _data[MAXLEN]; //... public: int& operator[](const int index) { return _data[index]; } const int operator[](const int index) const { return _data[index]; } //... };
const int operator[]
does make difference from int& operator[]
.
But what about:
int foo() { }
and
const int foo() { }
Seems like that they're the same.
My question is, why we use const int operator[](const int index) const
instead of int operator[](const int index) const
?
Thus, it's important to use const when returning an object by value if you want to prevent its use as an lvalue. The reason const has no meaning when you're returning a built-in type by value is that the compiler already prevents it from being an lvalue (because it's always a value, and not a variable).
You want to return a const reference when you return a property of an object, that you want not to be modified out-side of it. For example: when your object has a name, you can make following method const std::string& get_name(){ return name; }; . Which is most optimal way.
The const member functions are the functions which are declared as constant in the program. The object called by these functions cannot be modified. It is recommended to use const keyword so that accidental changes to object are avoided. A const member function can be called by any type of object.
Changing Value of a const variable through pointerThe compiler will give warning while typecasting and will discard the const qualifier. Compiler optimization is different for variables and pointers.
Top level cv-qualifiers on return types of non class type are ignored. Which means that even if you write:
int const foo();
The return type is int
. If the return type is a reference, of course, the const
is no longer top level, and the distinction between:
int& operator[]( int index );
and
int const& operator[]( int index ) const;
is significant. (Note too that in function declarations, like the above, any top level cv-qualifiers are also ignored.)
The distinction is also relevant for return values of class type: if you return T const
, then the caller cannot call non-const functions on the returned value, e.g.:
class Test { public: void f(); void g() const; }; Test ff(); Test const gg(); ff().f(); // legal ff().g(); // legal gg().f(); // **illegal** gg().g(); // legal
You should clearly distinguish between the const usage applying to return values, parameters and the function itself.
Return values
Consider const std::string SomeMethod() const
. It won't allow the (std::string&&)
function to be used, as it expects non-const rvalue. In other words, the returned string will always be copied.
const
protects the returned object from being modified.Parameters
Function itself
const
at the end, it can only run other const
functions, and can't modify or allow modification of class data. Thus, if it returns by reference, the reference returned must be const. Only const functions can be called on object or reference to object which is const itself. Also the mutable fields can be changed. this
reference to T const*
. The function can always const_cast
this
, but of course this shouldn't be done and is considered unsafe.Conclusion
If your method doesn't and never will modify the class variables, mark it as const and be sure to meet all the critieria needed. It will allow more cleaner code to be written, thus keeping it const-correct. However, putting const
everywhere without giving it any thought certainly isn't the way to go.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With