C++에서 static은 변수, 함수, 클래스 멤버에 각각 다른 의미로 사용되지만, 핵심은 항상 동일합니다:

static은 어떤 대상을 **“한 번만 생성되고, 프로그램의 전체 생명주기 동안 유지”**되게 만듭니다.

1. 정적 지역 변수 (Static Local Variables)

함수 내부에서 선언된 static 변수는 프로그램 시작 시 한 번만 초기화되고, 함수가 종료되어도 값이 유지됩니다.

#include <iostream>

int counter() {
    static int count = 0;  // 처음 호출 시에만 초기화
    return ++count;
}

int main() {
    std::cout << counter() << std::endl;  // 1
    std::cout << counter() << std::endl;  // 2
    std::cout << counter() << std::endl;  // 3
    return 0;
}

특징: 지역 변수의 스코프를 유지하면서 전역 변수의 수명을 가집니다. 스레드 안전한 초기화가 보장됩니다.

2. 정적 전역 변수/함수 (Static Global Variables/Functions)

파일 스코프에서 static으로 선언된 변수나 함수는 해당 파일 내에서만 접근 가능합니다.

// file1.cpp
static int internal_var = 100;  // 이 파일에서만 접근 가능
static void internal_function() {  // 이 파일에서만 접근 가능
    std::cout << "Internal function" << std::endl;
}

int global_var = 200;  // 다른 파일에서도 extern으로 접근 가능

용도: 내부 구현 세부사항을 숨기고, 이름 충돌을 방지합니다. C++에서는 anonymous namespace 사용을 더 권장합니다.

3. 클래스의 정적 멤버 변수 (Static Member Variables)

클래스의 모든 객체가 공유하는 변수입니다. 객체를 생성하지 않아도 접근할 수 있습니다.

class MyClass {
private:
    static int count;  // 선언
    int id;

public:
    MyClass() : id(++count) {}

    static int getCount() {  // 정적 멤버 함수
        return count;
    }

    int getId() const { return id; }
};

// 클래스 외부에서 정의 (필수)
int MyClass::count = 0;

int main() {
    std::cout << MyClass::getCount() << std::endl;  // 0

    MyClass obj1, obj2, obj3;
    std::cout << MyClass::getCount() << std::endl;  // 3

    std::cout << obj2.getId() << std::endl;  // 2
    std::cout << obj1.getId() << std::endl;  // 1
    std::cout << obj3.getId() << std::endl;  // 3

    return 0;
}

❓클래스 외부에서 정의해야하는 이유

4. 클래스의 정적 멤버 함수 (Static Member Functions)

객체 없이 호출할 수 있는 함수로, 비정적 멤버에는 접근할 수 없습니다.

class MathUtils {
public:
    static int add(int a, int b) {
        return a + b;
    }

    static double pi() {
        return 3.14159;
    }
};

int main() {
    // 객체 생성 없이 직접 호출
    int result = MathUtils::add(5, 3);
    double pi_value = MathUtils::pi();

    return 0;
}

5. Static 초기화와 메모리

class Resource {
private:
    static std::vector<int> data;  // 정적 멤버

public:
    static void initialize() {
        if (data.empty()) {
            data = {1, 2, 3, 4, 5};
            std::cout << "Static data initialized" << std::endl;
        }
    }

    static const std::vector<int>& getData() {
        return data;
    }
};

// 정적 멤버 정의
std::vector<int> Resource::data;