C++ 메모장

C++ static 에 대해 정리하고 가기

딴짓거리 2025. 3. 16. 23:17

1. 클래스 내부의 static 데이터 멤버와 메서드

클래스의 멤버중 static 키워드가 붙은 멤버는 그 객체에 속하지 않는다. 즉 객체의 외부에 단 하나만 존재하게 된다

 

일반적인 클래스 변수

class MyClass {
public:
    int x;
};

객체가 생성될때마다 개별적으로 메모리에 할당됨

모든 클래스의 인스턴스가 x를 개별적으로 가지게 됨

 

static 데이터 멤버

class MyClass
{
private:
    	static int x;
};

x를 인스턴스마다 따로 가지지 않고 클래스당 한개만 존재

클래스의 모든 인스턴스가 하나의 x를 공유함

#저 상태는 x가 선언만 된것이고 정의는 cpp 소스 파일에서 따로 해줘야됨

//MyClass.cpp

int MyClass::x

이렇게 정의만 하고 초기화 하지 않아도 자동으로 디폴트값인 0으로 초기화되며 포인터는 nullptr로 초기화 된다

물론 명시적으로 0으로 초기화 해도 된다

 

 

2. static 링크

함수나 전역 변수처럼 C++ 소스 파일마다 정의된 이름은 외부 링크나 내부 링크를 통해 서로 연결됨

외부 링크 - 다른 소스 파일에서 이름을 사용할 수 있음

내부 링크 - 같은 파일에서만 사용할 수 있음. (정적 링크라고도 부름)

 

함수나 글로벌 변수는 기본적으로 외부 링크가 적용됨

선언문 앞에 static 키워드를 붙이면 내부 링크가 적용됨

해당 소스 파일 내에서는 스코프에 관계없이 자유롭게 사용 가능

 

일반적으로 외부 링크가 적용되는 함수의 선언과 정의

//file1.cpp

void f();
int main()
{
    f();
}

//file2.cpp

void f();

void f()
{
    //some function
}

함수의 선언과 정의를 다른 파일에 분리해도 정상적으로 처리된다

f()가 외부 링크로 처리되고 main()은 다른 파일에 있는 함수를 호출할 수 있다

 

 

함수에 static 키워드를 붙인 경우

//file2.cpp

static void f();

void f()
{
    //some function
}

컴파일은 정상적으로 되지만 링크 단계에서 에러 발생

f()가 내부 링크로 변경되어 file1.cpp에서 f() 함수의 정의를 찾을 수 없게 되었다

 

3. static 로컬변수? static 전역변수?

일반적으로 한 소스 파일 내에서 공유할 목적으로 함수 외부에 선언한 static 변수는 static 전역변수이다

그렇다면 static 로컬변수는 무엇인가?

#include <iostream>

void counter() {
    static int count = 0;  //함수 내에서 static으로 선언
    count++;  
    std::cout << "Count: " << count << std::endl;
}

int main() {
    counter();  // 출력: Count: 1
    counter();  // 출력: Count: 2
    counter();  // 출력: Count: 3
}

static 변수가 특정 함수의 로컬 변수로 사용되었다

해당 함수가 처음 선언될때 단 한번만 초기화 되며, 여러번 호출되도 반복적으로 초기화되지 않는다

로컬 변수이지만 해당 값이 처음 선언될때부터 프로그램이 종료될때까지 값이 유지된다

 

 

extern?

간단하게 말하면 static과 반대로 외부링크로 만들어주는 키워드

단, extern키워드를 붙이면 컴파일러는 이를 정의가 아닌 선언으로 취급함

즉, 그 변수에 대해 메모리를 할당하지 않음

어딘가에 한번은 그 변수를 정의하는 문장을 따로 작성해야 한다.

extern은 " 이 변수는 다른 파일에서 정의될 것이니, 여기서 참조할 수 있도록 해줘 " 라는 의미

 

//file1.cpp

extern int a; // 선언만 되어있고 정의만 되어있음. a 사용 불가
//file2.cpp

int a = 1; //정의 완료. 이제 a를 어디에서나 사용할 수 있음

int func1()
{
    a = 5;
}
//file3.cpp

extern int a; // 다른 곳에 a가 정의되어있으니 그거 쓸께. 이렇게 해줘야 현재 파일에서 a 사용 가능!
// int a = 5; //중복 정의. 불가능!

int main()
{
    a = 10; //extern int a; 라고 알려줬기에 현재 파일에서 a를 사용 할 수 있다!
}