C++ "const" keyword explanation
When reading tuto开发者_JS百科rials and code written in C++, I often stumble over the const
keyword.
I see that it is used like the following:
const int x = 5;
I know that this means that x
is a constant variable and probably stored in read-only memory.
But what are
void myfunc( const char x );
and
int myfunc( ) const;
?
void myfunc(const char x);
This means that the parameter x
is a char whose value cannot be changed inside the function. For example:
void myfunc(const char x)
{
char y = x; // OK
x = y; // failure - x is `const`
}
For the last one:
int myfunc() const;
This is illegal unless it's inside a class declaration - const
member functions prevent modification of any class member - const
nonmember functions cannot be used. in this case the definition would be something like:
int myclass::myfunc() const
{
// do stuff that leaves members unchanged
}
If you have specific class members that need to be modifiable in const
member functions, you can declare them mutable
. An example would be a member lock_guard
that makes the class's const
and non-const
member functions threadsafe, but must change during its own internal operation.
The first function example is more-or-less meaningless. More interesting one would be:
void myfunc( const char *x );
This tells the compiler that the contents of *x
won't be modified. That is, within myfunc()
you can't do something like:
strcpy(x, "foo");
The second example, on a C++ member function, means that the contents of the object won't be changed by the call.
So given:
class {
int x;
void myfunc() const;
}
someobj.myfunc()
is not allowed to modify anything like:
x = 3;
This:
void myfunc( const char x );
means you you cannot change x
inside the function, i.e. this is illegal:
void myfunc( const char x ) {
x = ...;
}
while:
int myfunc() const;
only makes sense if myfunc() is a method inside a class; it basically means the method cannot modify the class instance (i.e. the state of the instance before and after calling instance.myfunc() will be the same).
Before a variable identifier, const
indicates that the variable can be initialized and thereafter not modified.
After a class method name, const
indicates that the method will not modify the observable state of the class. The mutable
keyword allows internal data to be modified.
Before a pointer or reference variable, const
indicates that the identifier will not be used to modify the referenced data, though it may be changed by other means.
const int *pInt = &x;
Const can also be used to indicate that the pointer itself cannot be modified:
int * const pInt = &x;
I've found a very good explanation at: http://duramecho.com/ComputerInformation/WhyHowCppConst.html
Basically all confusion lies in the different use cases for the keyword const
. Depending on where you place const
you tell that something should be immutable or something should not be able to change something else. 'something' might be a variable or a pointer or a function/method, which you don't want it to be able to change the value of variables passed to the functions or member variables of the object.
void myfunc(const char x)
is very similar to const int x = 5
in your example: It declares a constant locally available within the function myfunc
. As it is a constant its value cannot be changed.
int myfunc() const
is a member function of a class. The const
indicates that the function would not change the instance of the class the function is executed on. So, within the function, you cannot do something like this->foo = 7
or call other function that are not const.
The difference between the two is that the first has type void(char)
and the second has type int()const
.
A function that has such a type with const
at the end can only be a member function of a class, and it means that the member function does not change the class value (which this
refers to) as seen from outside the class. The compiler will check that to a degree, and any straight write to a class member in a const member function results in a compile time error, and the function can straightly only call const member functions on itself (special directives exist so you can tell the compiler that a member write won't change the class' value as seen from outside. This is done by the mutable
keyword).
In the functions you presented, one had a parameter of type char const
. Such a parameter cannot be changed inside its function. It has no effect on the function's type though, and no effect to the callers of the function.
The const
qualifier means that a variable/pointer defined as const
may not be changed by your program and it will receive its value either from an explicit initialization or by a hardware-dependent means.
A pointer that is defined as const
in the parameter declarations, the function code will not modify what it points to. Basically, you can use the pointer and it pretty much functions as a "read-only".
For example:-
void foo(const char *x)
{
while(*x)
{
if(*x==' ') cout << '-'; //printing - when a space is encountered
else cout << *x;
x++;
}
}
The above function is fine and won't show any errors. But if foo had any thing that could change the string passed. say a function that replaces spaces with $. Not print $ but changing it to $. Something like this:-
void foo(const char *x)
{
while(*x)
{
if(*x==' ') *x = '$'; //printing - when a space is encountered
else cout << *x;
x++;
}
}
then it would not compile i.e. an assignment error to a read-only memory location.
The accepted answer (and the others I skimmed) are not correct. Don't assume "const" means an identifier (like your x) "cannot be changed inside the function." It means the identifier can't be changed directly. But it can easily be changed.
Consider the full program (written out for newbies):
#include <iostream>
void break_const(const int x) {
const int* x_ptr = &x;
std::intptr_t z = reinterpret_cast<std::intptr_t>(x_ptr);
int* hacked = reinterpret_cast<int*>(z);
*hacked = 3;
std::cout << "x = " << x << std::endl;
}
int main() {
break_const(5);
return 0;
}
The output is "x = 3."
Edit: I should also add that my statement "It means the identifier can't be changed directly" is a bit off. For ints, it's fine. But for more complicated types, const means even less (e.g., mutable in a class).
精彩评论