views:

158

answers:

6

When reading tutorials 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;

?

A: 

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.

Johannes Schaub - litb
While those types are certainly correct, they're _very_ likely babble to newbies.
sbi
+1  A: 

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).

Lie Ryan
A: 

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.

Flinsch
+6  A: 
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)
{
  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.

Steve Townsend
@Charles, thanks - I was editing that in as you commented...
Steve Townsend
the whole point of it being not to enable the use of const methods, but to be able to call any methods on a const object... so a mutable member is not a member that can change in a const method, it is much more a member that is allowed to change on an otherwise const object.
ufotds
@ufotds - correct - don't make stuff `mutable` just because your code won't compile through misunderstanding of the meaning of `const` on member functions.
Steve Townsend
+3  A: 

The first function example is more-or-less meaningless. More interesting 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;
Paul Roub
The first example can actually help the compiler producing more optimal code, although most modern compilers will most likely figure out them selves if the variable is not modified.
TommyA
The first example also prevents accidental modifications. While it's irrelevant from the perspective of the caller, it's sometimes quite helpful to declare every parameter and local variable `const` since modifying them can point to mistakes or bad design.
Philipp
Even if it was meaningless (which it isn't at all, I'm with @Philipp on this), you should at least have explained _why_. (But don't bother do this now when you have been told it's wrong.)
sbi
A: 

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;
Andy Thomas-Cramer