What is a const function? Const functions are defined like
int fun() const
But only a member function can be const, i.e., there is no concept of const function outside a class. If you define a “const function” outside a class, you will get the following error:
error: non-member function ‘int fun()’ cannot have cv-qualifier
This is related to why we need a const function. The keyword const that is appended to the function tells the compiler that the statements in the function can not modify the value of the members of the class. If the compiler sees some statement in the class try to modify a class member, it will complain an error:
class A { public: int a; int geta()const; }; int A::geta()const { a=1234; return a; }
When compiling the above code, the compiler reports the following error:
error: assignment of data-member ‘A::a’ in read-only structure
This is why const functions can only be defined for a class(i.e., member function).
Note that the the const keyword must be added for both the function declaration(inside the class definition) and the function implementation(outside the class definition), otherwise you will get the following error:
error: prototype for ‘int A::geta()’ does not match any in class ‘A’ (missing const in function implementation)
or
error: prototype for ‘int A::geta() const’ does not match any in class ‘A’(missing const in function declaration)
This is because the const keyword is part of the function prototype, which is unlike the default parameter value that is not part of the function prototype.
Note that const function and function that returns constant value are two different things. A const function can return either a const value or a non-const value. Likewise, a non-const function can return either a non-const value or a constant value. If a function(const or non-const) returns a constant value, it’s typically a constant reference such as:
class A { public: int a; const int &geta()const; }; const int& A::geta()const { return a; }
Because if a function returns a constant non-reference value, the value can only be used as a right-value which will never be altered thus the const keyword loses its value. If you try to assign a value to the returned non-reference value like:
class A { public: int a; const int geta()const; }; const int A::geta()const { a=1234; return a; } A aa; aa.geta()=4321;
You’ll get the compiling error:
error: lvalue required as left operand of assignment
This behavior is understandable as the returned value is just a temporary object and will be destroyed right after the statement, making the assignment meaningless.
A (returned) reference can be used as left-value and can be assigned a value. To avoid the returned reference value being modified, you should return a const reference (to a member variable or a global variable).
Since “int fun() const” and “int fun()” have different signatures, they can overload each other in a class. When you call fun on a const object, you are actually calling the const function. When you call fun on a non-const object, you are actually calling the non-const function.
class A { public: int a; int geta()const; int geta(); }; int A::geta()const { return a; } int A::geta() { return a; } A aa; aa.geta(); //call int A::geta() const A bb; bb.geta();//call int A::geta()const