Appearance
Const and Pointers
Video: CONST in C++
The const keyword makes something read-only - it prevents modification of the declared entity. This applies to:
- Variables: Cannot be changed after initialization
- Function parameters: Cannot be modified within the function
- Member functions: Cannot modify the object's state
- Return values: Cannot be modified by the caller
Basic Const with Pointers
Const Value, Non-const Pointer
cpp
const int value = 42;
int* ptr = &value; // ERROR: Cannot assign const int* to int*
const int* ptr = &value; // OK: Pointer to const intWhat this means:
- The
intvalue cannot be modified through the pointer - The pointer itself can be reassigned to point to other const ints
- You cannot dereference and modify the pointed value
cpp
const int x = 10;
const int y = 20;
const int* ptr = &x; // ptr points to x
*ptr = 30; // ERROR: Cannot modify const int
ptr = &y; // OK: Can reassign pointerNon-const Value, Const Pointer
cpp
int value = 42;
int* const ptr = &value; // Const pointer to non-const intWhat this means:
- The pointer cannot be reassigned to point elsewhere
- The value it points to can be modified
- The pointer is "locked" to one location
cpp
int x = 10;
int y = 20;
int* const ptr = &x; // ptr points to x
*ptr = 30; // OK: Can modify the value
ptr = &y; // ERROR: Cannot reassign const pointerMultiple Levels of Constness
Const Pointer to Const Value
cpp
const int value = 42;
const int* const ptr = &value; // Const pointer to const intWhat this means:
- The pointer cannot be reassigned
- The value cannot be modified through the pointer
- Maximum immutability - both pointer and value are locked
cpp
const int x = 10;
const int y = 20;
const int* const ptr = &x; // ptr points to x
*ptr = 30; // ERROR: Cannot modify const int
ptr = &y; // ERROR: Cannot reassign const pointerConst Pointer to Non-const Value
cpp
int value = 42;
int* const ptr = &value; // Const pointer to non-const intWhat this means:
- The pointer cannot be reassigned
- The value can be modified through the pointer
- Pointer is locked, but value is mutable
cpp
int x = 10;
int y = 20;
int* const ptr = &x; // ptr points to x
*ptr = 30; // OK: Can modify the value
ptr = &y; // ERROR: Cannot reassign const pointerReading Const Declarations
The key to understanding const with pointers is to read from right to left:
cpp
int const* ptr; // ptr is a pointer to const int
int* const ptr; // ptr is a const pointer to int
int const* const ptr; // ptr is a const pointer to const intMemory trick: The const applies to whatever is immediately to its left (except when it's the leftmost keyword).
So for example these statements are the same:
cpp
int const* ptr; // ptr is a pointer to const int
const int* ptr; // ptr is a pointer to const intPractical Examples
Function Parameters
cpp
// Function cannot modify the string it receives
void printString(const char* str) {
while (*str) {
std::cout << *str;
str++; // OK: Can modify the pointer
// *str = 'X'; // ERROR: Cannot modify the string
}
}
// Function cannot modify the pointer or the string
void printStringFixed(const char* const str) {
while (*str) {
std::cout << *str;
// str++; // ERROR: Cannot modify the pointer
// *str = 'X'; // ERROR: Cannot modify the string
}
}Class Members
cpp
class StringManager {
private:
char* const data; // Pointer cannot be reassigned
const size_t capacity; // Capacity cannot be modified
public:
StringManager(char* str, size_t cap) : data(str), capacity(cap) {}
void modifyString() {
// data = new char[100]; // ERROR: Cannot reassign const pointer
data[0] = 'X'; // OK: Can modify the string content
// capacity = 200; // ERROR: Cannot modify const member
}
};Const Correctness Best Practices
- Make everything const by default: Only remove const when you need mutability
- Use const references: Prefer
const T&overconst T*when possible - Const member functions: Mark member functions as const when they don't modify state
- Return const: Return const references/pointers when the caller shouldn't modify the data
Common Pitfalls
1. Const Cast Abuse
cpp
const int value = 42;
const int* ptr = &value;
int* mutable_ptr = const_cast<int*>(ptr); // DANGEROUS!
*mutable_ptr = 100; // Undefined behavior - modifying const object2. Ignoring Const in Function Signatures
cpp
void process(const int* data, int size); // Good: Won't modify data
void process(int* data, int size); // Bad: Suggests data might be modified3. Forgetting Const in Return Types
cpp
class Container {
int* data;
public:
int* getData() const { return data; } // Bad: Allows modification
const int* getData() const { return data; } // Good: Prevents modification
};Questions
Q: What does const int ptr mean?*
const int* ptr means a non-const pointer to a const int. The pointer can be reassigned, but the value it points to cannot be modified.
Q: What does int const ptr mean?*
int* const ptr means a const pointer to a non-const int. The pointer cannot be reassigned, but the value it points to can be modified.
Q: What does const int const ptr mean?*
const int* const ptr means a const pointer to a const int. Both the pointer and the value it points to are const - maximum immutability.
Q: When should you prefer const references over const pointers?
Const references are preferred when you want to prevent accidental null pointer dereferences. References must always refer to valid objects, making code safer.
Q: Why is const correctness important in C++?
A: It makes code run faster
Const correctness prevents accidental modifications and improves code safety by making the compiler catch potential errors at compile time.