Const Correctness
Using const to specify immutability and prevent accidental modifications
Learn how to use const to make your intentions clear and prevent bugs by specifying which values should not change.
A Simple Example
#include <iostream>
#include <string>
int main() {
const int max{100}; // Cannot change max
// max = 200; // ERROR! Cannot modify const
// Const reference parameter
const std::string message{"Hello"};
// message = "Bye"; // ERROR! Cannot modify const
int value{42};
const int& ref{value}; // Const reference to non-const value
// ref = 50; // ERROR! Cannot modify through const reference
value = 50; // OK! Can modify value directly
return 0;
}
Breaking It Down
Const Variables: const int x{10};
- What it does: Creates a variable whose value cannot be changed after initialization
-
Must initialize:
const int x{10};is required - can't declare without a value - Compiler enforced: Trying to modify const variables causes compile-time errors
- Remember: Use const for values that should never change like max limits, pi, etc.
Const References: const Type& param
- What it does: Prevents modifying the referenced object through this reference
- Best for parameters: Avoids copying large objects while preventing modification
- Performance + safety: Gets benefits of pass-by-reference without the risk
-
Remember: Use
const Type&for read-only function parameters
Const Pointers: Two Flavors
-
const int* p: Pointer to const int - can't change value through pointer -
int* const p: Const pointer to int - can't change where pointer points -
const int* const p: Both const - can't change value or pointer -
Remember: Read right-to-left:
const int*= "pointer to const int"
Const Member Functions: void func() const
- What it does: Promises not to modify the object
-
Syntax:
void getName() const { return name; } - Can call on const objects: Only const member functions can be called on const objects
- Remember: Mark getter methods as const to allow them on const objects
Why This Matters
- Prevents bugs by making intentions clear - the compiler enforces that const values don't change.
- Enables compiler optimizations - const allows the compiler to make better optimization decisions.
- Documents which functions modify state - seeing const in a signature tells you the function won't modify the parameter.
Critical Insight
const references give you the performance of passing by reference with the safety of passing by value. Best of both worlds!
When you pass by value, the entire object is copied (slow for large objects). When you pass by reference, modifications affect the original. But const Type& gives you no copying AND no accidental modifications - it's the perfect choice for read-only parameters.
Best Practices
Use const by default: Start with const and remove it only if you need to modify the value. This prevents accidental changes.
Const references for parameters: Use const Type& for read-only parameters of large objects to avoid copying.
Mark getters as const: Member functions that don't modify the object should be marked const so they work with const objects.
Read const pointers carefully: const int* p (pointer to const) is different from int* const p (const pointer). Read right-to-left.
Common Mistakes
const int* p vs int* const p: Order matters! const int* p = "pointer to const int", int* const p = "const pointer to int".
Const member functions limitations: const member functions can only call other const member functions on member objects.
Cannot pass const to non-const reference: Can't pass const objects to non-const reference parameters - the function might modify them.
Const only prevents modification through that variable: const int& ref{x}; x = 10; works - x itself is not const, only the reference.
Debug Challenge
This function should display a Player without modifying it. Click the highlighted line to fix the parameter:
Quick Quiz
- What does
const int* pmean?
- Why use const references for function parameters?
- Can you call a non-const member function on a const object?
Practice Playground
Time to try out what you just learned! Play with the example code below, experiment by making changes and running the code to deepen your understanding.
Output:
Error:
Lesson Progress
- Fix This Code
- Quick Quiz
- Practice Playground - run once