C++ Const and Mutable Modifiers Explained
Understanding C++ Const and Mutable Modifiers
In C++, the const keyword is used to declare constants or immutable values. It can be applied to variables, pointers, function parameters, member functions, and more. Using const enhances code safety and readability by preventing accidental modifications.
Constant Variables
Variables declared as const cannot be modified after initialization.
#include <iostream>
int main() {
const int MAX_SIZE = 100;
// MAX_SIZE = 200; // Error: cannot modify const variable
std::cout << "Maximum size: " << MAX_SIZE << std::endl;
return 0;
}
Constant Pointers
Pointer to Constant Data
A pointer to constant data cannot modify the value it points to. The syntax is const type* or type const*.
#include <iostream>
int main() {
int data = 42;
const int* dataPtr = &data; // or int const* dataPtr = &data;
std::cout << "Data value: " << *dataPtr << std::endl;
// Attempt to modify pointed value (causes compilation error)
// *dataPtr = 100; // Error: cannot modify through pointer to const
data = 100; // Can modify variable directly
std::cout << "Updated data: " << *dataPtr << std::endl;
return 0;
}
Constant Pointer
A constant pointer itself is immutable after initialization. The syntax is type* const.
#include <iostream>
int main() {
int value1 = 25;
int value2 = 50;
int* const fixedPtr = &value1;
std::cout << "Value: " << *fixedPtr << std::endl;
// Attempt to modify pointer itself (causes compilation error)
// fixedPtr = &value2; // Error: cannot modify constant pointer
// Can modify value through pointer
*fixedPtr = 75;
std::cout << "Modified value: " << *fixedPtr << std::endl;
return 0;
}
Constant Pointer to Constant Data
Both the pointer and the data it points to are immutable. The syntax is const type* const or type const* const.
#include <iostream>
int main() {
int number = 30;
const int* const immutablePtr = &number;
// *immutablePtr = 40; // Error: cannot modify const value
// immutablePtr = &other; // Error: cannot modify const pointer
std::cout << "Number: " << *immutablePtr << std::endl;
return 0;
}
Constant Function Parameters
Value Parameters
Using const with value parameters has no effect since the function works with a copy.
void process(int param) {
// param is a copy
}
Pointer Parameters
Pointer parameters can be marked as const to prevent modification of the pointed value.
void display(const int* ptr) {
// *ptr = 10; // Error: cannot modify const pointer's target
std::cout << "Value: " << *ptr << std::endl;
}
Reference Parameters
Reference parameters can be marked as const to prevent modification of the referenced value.
void calculate(const int& ref) {
// ref = 20; // Error: cannot modify const reference
std::cout << "Result: " << ref * 2 << std::endl;
}
Constant Member Functions
A member function declared as const cannot modify the object's member variables.
#include <iostream>
class DataProcessor {
public:
DataProcessor(int val) : value(val) {}
// Constant member function
int getValue() const {
// value = 20; // Error: cannot modify in const function
return value;
}
private:
int value;
};
int main() {
DataProcessor processor(15);
std::cout << "Value: " << processor.getValue() << std::endl;
return 0;
}
Const and Mutable
The mutable keyword allows modification of specific member variables even in const member functions. It's often used for debugging counters or temporary variables.
#include <iostream>
class SafeCounter {
public:
SafeCounter(int initial) : count(initial) {}
int getCount() const {
accessCount++; // Allowed due to mutable
return count;
}
int getAccessCount() const {
return accessCount;
}
private:
int count;
mutable int accessCount;
};
int main() {
SafeCounter counter(5);
counter.getCount();
std::cout << "Access count: " << counter.getAccessCount() << std::endl;
return 0;
}
Constant Return Types
Functions can return const values to prevent modification of the returned result.
#include <iostream>
const int& getReference(const int& source) {
return source;
}
int main() {
int input = 8;
const int& resultRef = getReference(input);
// resultRef = 16; // Error: cannot modify const reference
std::cout << "Result: " << resultRef << std::endl;
return 0;
}