#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;
}

results matching ""

    No results matching ""