#include <iostream>
#include <string>

// ========================= 1. Static Global Variables and Static Functions at File Scope =========================
// Static global variable: only visible within this file, cannot be linked from other source files
static int s_fileCounter = 100;

// Static function: only visible within this file, avoids conflicts with functions of the same name in other files
static void printFileMessage(const std::string& msg) {
    std::cout << "[FileScope] " << msg << std::endl;
}

// ========================= 2. Regular Function Demonstrating Static Local Variables =========================
int incrementCallCount() {
    // Static local variable: lifetime spans the entire program execution, initialized only on first call
    static int callCount = 0;
    callCount++;
    std::cout << "incrementCallCount has been called " << callCount << " times" << std::endl;
    return callCount;
}

// ========================= 3. Class Demonstrating Static Member Variables and Static Member Functions =========================
class ObjectCounter {
private:
    static int s_totalObjects;      // Static member variable declaration (shared by all objects)
    int m_id;

public:
    ObjectCounter() : m_id(s_totalObjects + 1) {
        ++s_totalObjects;
        std::cout << "Created object #" << m_id << ", current total objects = " << s_totalObjects << std::endl;
    }

    ~ObjectCounter() {
        --s_totalObjects;
        std::cout << "Destroyed object #" << m_id << ", remaining objects = " << s_totalObjects << std::endl;
    }

    // Static member function: can only access static members, called directly through class name
    static int getTotalObjects() {
        return s_totalObjects;
    }

    // Static member functions can access private static members, commonly used for factory or utility methods
    static void showStatistics() {
        std::cout << "[ObjectCounter] Current active object count: " << s_totalObjects << std::endl;
    }
};

// Definition of static member variable (must be done outside the class, without repeating static keyword)
int ObjectCounter::s_totalObjects = 0;

// ========================= 4. Singleton Pattern Using Static Local Variable (Thread-safe since C++11) =========================
class Singleton {
private:
    Singleton() {
        std::cout << "Singleton instance created" << std::endl;
    }
    ~Singleton() = default;

public:
    // Disable copy and assignment
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

    // Singleton implementation using static local variable: initialized on first call, destroyed at program end
    static Singleton& getInstance() {
        static Singleton instance;   // Static local variable ensures unique instance
        return instance;
    }

    void doSomething() const {
        std::cout << "Singleton performing operation, address = " << this << std::endl;
    }
};

// ========================= 5. Additional Demo: Static Constant Members (C++ allows in-class initialization for integer/enum static const) =========================
class MathConstants {
public:
    static const double PI;          // Declaration, defined outside class
    static const int MAX_VALUE = 100; // Integer constants can be initialized in-class (constexpr also supported since C++11)
    static constexpr double E = 2.71828; // More modern to use constexpr since C++11
};

// Need to define static const non-integer members outside the class (before C++17)
const double MathConstants::PI = 3.141592653589793;

// ========================= Main Function =========================
int main() {
    std::cout << "========== C++ static Keyword Demonstration ==========" << std::endl;

    // ---------- 1. Static global variables and functions at file scope ----------
    std::cout << "\n--- File scope static ---" << std::endl;
    printFileMessage("Static function call");
    std::cout << "Initial value of static global variable s_fileCounter = " << s_fileCounter << std::endl;
    s_fileCounter += 50;
    std::cout << "After modification s_fileCounter = " << s_fileCounter << std::endl;

    // ---------- 2. Static local variables inside functions ----------
    std::cout << "\n--- Static local variables ---" << std::endl;
    incrementCallCount();
    incrementCallCount();
    incrementCallCount();  // Call count accumulates

    // ---------- 3. Static member variables and static member functions of a class ----------
    std::cout << "\n--- Class static members ---" << std::endl;
    ObjectCounter::showStatistics();  // Initially 0

    ObjectCounter obj1;
    ObjectCounter obj2;
    {
        ObjectCounter obj3;  // Local scope
        std::cout << "Inside scope, get total via static function: " << ObjectCounter::getTotalObjects() << std::endl;
    } // obj3 destroyed
    ObjectCounter obj4;

    ObjectCounter::showStatistics();

    // ---------- 4. Static local variable in singleton pattern ----------
    std::cout << "\n--- Singleton using static local variable ---" << std::endl;
    Singleton& s1 = Singleton::getInstance();
    Singleton& s2 = Singleton::getInstance();
    s1.doSomething();
    s2.doSomething();
    if (&s1 == &s2) {
        std::cout << "s1 and s2 are the same instance, same address: " << &s1 << std::endl;
    }

    // ---------- 5. Static constant members ----------
    std::cout << "\n--- Static constant members ---" << std::endl;
    std::cout << "MathConstants::PI = " << MathConstants::PI << std::endl;
    std::cout << "MathConstants::MAX_VALUE = " << MathConstants::MAX_VALUE << std::endl;
    std::cout << "MathConstants::E = " << MathConstants::E << std::endl;

    std::cout << "\n========== Program End ==========" << std::endl;
    return 0;
}

results matching ""

    No results matching ""