In C++, the const keyword plays a crucial role in enforcing immutability, ensuring that certain data or operations cannot be modified after initialization or within specific contexts. This section explores its application to member variables and member functions.
constMember Variables
When a member variable is declared as const, it signifies that its value cannot be altered after the object is constructed. To achieve this:
constmember variables must be initialized using the constructor's initializer list.- They cannot be modified within the class's methods after initialization.
- Initialization is mandatory.
Consider the following class definition:
class DataContainer {
public:
// Constructor using initializer list
DataContainer(int initialValue, const std::string& initialName)
: value(initialValue), name(initialName) {}
~DataContainer() {
// Destructor implementation
}
void display() const { // Example of a const member function
std::cout << "Value: " << value << ", Name: " << name << std::endl;
}
private:
int value;
const std::string name; // 'name' is a const member variable
};
An example of its usage:
int main() {
DataContainer obj(42, "Sample");
obj.display();
// obj.name = "New Name"; // This line would cause a compile-time error
return 0;
}
constMember Functions
A const member function is a member function declared with the const specifier after its parameter list. This indicates that the function promises not to modify the state of the object its called upon. Key characteristics include:
- The
constkeyword is placed after the function's parameter list. - Inside a
constmember function, member variables of the class cannot be modified. - A class can have both non-
constandconstversions of the same member function. - Object type determines which version is called:
- Non-
constobjects can call both non-constandconstmember functions. Non-constfunctions are preferred if available. constobjects can only callconstmember functions.
- Non-
Code Example:
Class Definition:
class Item {
public:
Item() : quantity(0) {}
Item(int initialQuantity, const std::string& itemName)
: quantity(initialQuantity), name(itemName) {}
~Item() {}
void printDetails(); // Non-const member function
void printDetails() const; // Const member function
bool isLarger(const Item& other) const; // Const member function for comparison
void updateQuantity(int newQuantity); // Non-const member function
};
Member Function Implementations:
void Item::printDetails() {
std::cout << "Non-const print: Quantity=" << quantity << ", Name=" << name << std::endl;
}
void Item::printDetails() const {
std::cout << "Const print: Quantity=" << quantity << ", Name=" << name << std::endl;
}
bool Item::isLarger(const Item& other) const {
return this->quantity > other.quantity;
}
void Item::updateQuantity(int newQuantity) {
this->quantity = newQuantity; // Allowed because this is a non-const function
}
Usage in main:
int main() {
Item item1(10, "Gadget");
const Item item2(25, "Widget");
const Item item3(30, "Thingamajig");
// Calling printDetails()
item1.printDetails(); // Calls the non-const version
item2.printDetails(); // Calls the const version (only option for const object)
item3.printDetails(); // Calls the const version
// Comparisons
// item1.isLarger(item2) can be called either as item1.isLarger(item2) or item2.isLarger(item1)
// If item1 is the caller, it can call a const function on item2.
if (item1.isLarger(item2)) {
std::cout << "item1 is larger than item2" << std::endl;
} else {
std::cout << "item2 is larger than or equal to item1" << std::endl;
}
// item1.updateQuantity(15); // Can call non-const function on non-const object
// item2.updateQuantity(5); // Error: const object cannot call non-const member function
// item2.isLarger(item3); // This is valid, as isLarger is a const member function
return 0;
}
- Understanding Pointer Qualifiers:
const char\*vs.char\* const
The placement of const with pointers significantly changes their meaning:
-
const char* ptr;(orchar const* ptr;): This declaresptras a pointer to a constant character. The data pointed to byptrcannot be modified through this pointer. However, the pointer itself can be made to point to a different location. ```const char* message = "Hello"; // message[0] = 'J'; // Error: Cannot modify through a pointer to const message = "World"; // Okay: The pointer itself can be reassigned
-
char* const ptr;: This declaresptras a constant pointer to a character. The pointer itself cannot be reassigned to point to a different memory location. However, the data it points to can be modified (if the data itself is not const). ```char buffer[] = "Initial"; char* const fixedPtr = buffer; fixedPtr[0] = 'M'; // Okay: Modifying the data pointed to // fixedPtr = nullptr; // Error: Cannot reassign a const pointer
For a more in-depth explanation, refer to resources discussing the distinctions between const char*, char const*, and char* const.