#include <iostream>
#include <string>
#include <vector>
// ========================= Helper Functions =========================
// 1. const reference parameter: avoid copying, while ensuring the original object is not modified
void printString(const std::string& str) {
// str += "!"; // Uncommenting will cause compilation error
std::cout << "[const ref] " << str << std::endl;
}
// 2. const pointer parameter: ensure the function does not modify the content pointed to by the pointer
void processArray(const int* arr, size_t size) {
std::cout << "[const pointer param] array: ";
for (size_t i = 0; i < size; ++i) {
// arr[i] *= 2; // Error: cannot modify const int*
std::cout << arr[i] << " ";
}
std::cout << std::endl;
}
// 3. return const value: prevent caller from modifying the return value
const int getConstValue() {
return 42;
}
// ========================= Demo Class =========================
class ConstDemo {
private:
const int id_; // const member variable, must be initialized in the initialization list
int value_;
mutable int accessCount_; // mutable: allows modification in const member functions
public:
// Constructor: initialize const member through initialization list
ConstDemo(int id, int val) : id_(id), value_(val), accessCount_(0) {}
// const member function: does not modify regular members, but can modify mutable members
int getId() const {
// id_ = 100; // Error: cannot modify const member
accessCount_++; // OK: mutable members can be modified in const functions
return id_;
}
int getValue() const {
accessCount_++;
return value_;
}
// Non-const member function: can modify regular members
void setValue(int newVal) {
value_ = newVal;
}
// Display access count (to observe mutable behavior)
void showAccessCount() const {
std::cout << "[mutable] accessCount_ = " << accessCount_ << std::endl;
}
};
constexpr int SQUARE(int x) { return x * x; } // C++11 allows constexpr functions
// ========================= Main Function =========================
int main() {
std::cout << "========== Comprehensive Demo of const Keyword ==========\n\n";
// ---------- 1. Define constant variables ----------
std::cout << "1. Constant Variables\n";
const double PI = 3.1415926;
// PI = 3.14; // Compilation error: cannot modify const variable
std::cout << "const double PI = " << PI << std::endl;
std::cout << "Attempting to modify PI causes compilation error (commented out)\n\n";
// ---------- 2. const with pointers ----------
std::cout << "2. const with Pointers\n";
int value = 100;
int another = 200;
// 2.1 pointer to const
const int* ptr1 = &value;
// *ptr1 = 999; // Error: cannot modify content through ptr1
ptr1 = &another; // OK: pointer itself can change
std::cout << "Pointer to const: *ptr1 = " << *ptr1 << " (points to another)" << std::endl;
// 2.2 const pointer
int* const ptr2 = &value;
*ptr2 = 999; // OK: can modify pointed content
// ptr2 = &another; // Error: pointer itself is constant, cannot change
std::cout << "Const pointer: *ptr2 = " << *ptr2 << " (value changed to 999)" << std::endl;
// 2.3 const pointer to const
const int* const ptr3 = &value;
// *ptr3 = 123; // Error
// ptr3 = &another; // Error
std::cout << "Const pointer to const: *ptr3 = " << *ptr3 << " (read-only, fixed pointer)\n\n";
// ---------- 3. const references ----------
std::cout << "3. const References\n";
int num = 50;
const int& ref = num; // const reference, cannot modify original value through reference
// ref = 60; // Error
num = 60; // Original variable can still be modified
std::cout << "const int& ref = num; num = " << num << ", ref = " << ref << std::endl;
// const reference can bind to temporary objects (extends lifetime)
const int& tempRef = 123;
std::cout << "const reference bound to temporary value: " << tempRef << std::endl;
printString("Hello const reference"); // Demonstrate function parameter
std::cout << std::endl;
// ---------- 4. const function parameters ----------
std::cout << "4. const Function Parameters\n";
int arr[] = {10, 20, 30, 40};
processArray(arr, 4); // Array guaranteed not modified inside function
std::cout << std::endl;
// ---------- 5. const member functions and mutable ----------
std::cout << "5. const Member Functions and mutable\n";
ConstDemo obj(101, 500);
std::cout << "obj.getId() = " << obj.getId() << std::endl;
std::cout << "obj.getValue() = " << obj.getValue() << std::endl;
obj.showAccessCount(); // accessCount_ has been modified twice by const member functions
const ConstDemo constObj(202, 888); // const object
std::cout << "constObj.getId() = " << constObj.getId() << std::endl;
// constObj.setValue(999); // Error: const object cannot call non-const member functions
constObj.showAccessCount();
std::cout << std::endl;
// ---------- 6. const member variables and initialization list ----------
std::cout << "6. const Member Variables (already demonstrated in ConstDemo class, id_ cannot be modified)\n";
// Attempt to modify obj's id_? No public interface, can only initialize once through constructor
std::cout << "obj's id_ = " << obj.getId() << " (immutable)\n\n";
// ---------- 7. const return values ----------
std::cout << "7. const Return Values\n";
const int ret = getConstValue();
std::cout << "getConstValue() = " << ret << std::endl;
// getConstValue() = 100; // Compilation error: returns const int, cannot be modified as lvalue
std::cout << "Attempting to modify return value causes compilation error (commented out)\n\n";
// ---------- 8. constexpr (compile-time constant) ----------
std::cout << "8. constexpr (Compile-Time Constant)\n";
constexpr int N = SQUARE(7); // Computed at compile time
std::cout << "constexpr int N = SQUARE(7); N = " << N << std::endl;
// constexpr int M = SQUARE(std::rand()); // Error: std::rand() is not a compile-time constant
std::cout << "constexpr requires initializer to be a compile-time constant, otherwise compilation error\n\n";
std::cout << "========== Demo Complete ==========\n";
return 0;
}