[Home]  [Edit this page]  [Recent Changes]  [Special Pages]  [Help
CppConst

(C++) const

Keyword being an abbreviation of 'constant'. Use const whenever possible [3-7].

Using the const keyword: A consequent use of the const keyword is termed const correctness.

Be suspicious of non-const reference arguments; if you want the function to modify its arguments, use pointers and value return instead [1]. Use const reference arguments when you need to minimize copying of arguments [2]. Use const extensively and consistently [3-7].

Page overview

== Errors can be spotted at compile-time ==

The most basic use:
const unsigned int notesPerChord = 12;
//Do something with this knowledge
++notesPerChord; //ERROR! Cannot change a constant


Although in the example given above, it is obvious from reading the variable name notesPerChord, that it shouldn't change, as it is a fact. However, when using many short variable names like 'npc' instead of 'notesPerChord', you could accidentaly increment it. Then, the compiler will at least warn you.

== The meaning of a function gets more clear == A function declaration is the first impression of a function as it summarizes the effect of the variables involved or produced. Two 'natural' feeling functions are:

double calculateCircleArea(const double& ray); 
In the process of calculating the area of a circle from its ray, the value of 'ray' does not need to be changed (therefore its const). Also, it does not need to be copied (therefore the reference operator.

void swap(int& a, int& b); 
When swapping two values by reference, there will no number be calculated in the process (therefore its a void function. But both variables will/can be changed in the process, therefore the reference operator '&'.

Many newbies do not use const and referencing, yielding code like:
int calculateSquare(int value);
Newbies are easily spotted from their function  ?prototypes. In this function the value of 'value' is copied, squared and returned. Why make a copy? The only reason you WANT a copy is when e.g. using a function that uses referencing or when you temporarily want to modify a copy of a variable:
void performMagic(const std::string& myString)
{
  const std::string copyString = myString;
  copyString[0] = "X";
  std::cout << copyString << std::endl;
}
In this case, you just use:
void performMagic(std::string myString)
{
  myString[0] = "X";
  std::cout << myString << std::endl;
}
A good example of this, is in this function

The meaning of a function gets more clear, now using pointers

When using pointers, const can be used twice for every argument.

struct MyStruct { int mX; };
void transmogrify1(const MyStruct * pMyStruct)
{
  // pMyStruct->mX = 12; //Error: cannot modify where pMyStruct points to
  pMyStruct = 0;         // Okay, won't do harm to pMyStruct
}
void transmogrify2(MyStruct * const pMyStruct)
{
  pMyStruct->mX = 12; // Okay, can modify where pMyStruct points to 
  // pMyStruct = 0;   // Error: cannot modify pointer
}
void transmogrify3(const MyStruct * const pMyStruct)
{
  // pMyStruct->mX = 12; // Error: cannot modify where pMyStruct points to
  // pMyStruct = 0;      // Error: cannot modify pointer 
}


To indicate that MyStruct is only read from, use transmogrify1 and transmogrify3. To save typing, many choose transmogrify1.

== The effect a class member function has gets more clear ==

In a class, when you see the following member function:
double MyClass
{
  double getValue() const { /* SOMETHING */ }
};
you know its a function that does not alter the member variables or the class.

But imagine that getting this value is a very time-intensive process. Then you might want the class to also store the amount of times this function has been called. Then you would use:

class MyClass
{
  double getValue()
  {
    ++mRequests; //A member variable
    return mValue;
  }
};


Although this is one of those occasions to use mutable, as every programmer expects a getter to be const:

class MyClass
{
  mutable int mRequests;
  double getValue()
  {
    ++mRequests; //A member variable
    return mValue;
  }
};


Other questions

=== How do I initialize a const member variable ? === Using the constructor's initialization list:

  1. include <iostream>
class MyMultiplier { const int mMultiplier; public: MyMultiplier(const int& value) : //Colon means 'start init list' mMultiplier(value) //Initialization list has slightly different syntax { //Nothing } int multiply(const int otherValue) const { return (otherValue * mMultiplier); } }; int main() { MyMultiplier multiplier(69); std::cout << multiplier.multiply(96) << std::endl; }


=== I have another question === Check out C++ FAQ LITE.

== Code links ==

'const' links

References



last edited (January 10, 2007) by bilderbikkel, Number of views: 15485, Current Rev: 30 (Diff)

[Edit this page]  [Page history]  [What links here]  [Discuss this topic]  [Printer Friendly]  

Members

Username:

Password:


Register
Forgot Password?




Programmers Heaven - for .NET, Java, C/C++ and WEB Developers!
© 1996-2008 Community Networks Ltd. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited. Violators of this policy may be subject to legal action. Please read Terms Of Use and Privacy Statement for more information. Development by Tore Nestenius at .NET Consultant - Synchron Data.