개노답 삼형제

invisible_thorn·2025년 5월 14일
0
post-thumbnail

맨날 헷갈리는 개노답 삼형제 모셨습니다.
static, extern, const 차례로 박살 내보죠.
는 내가 부숴질 예정

static의 개념은 전역변수의 특징을 조금 가지고 있는데요,
전역변수의 특징에는 무엇이 있을까요?

1. data 영역에 적재된다.
2. 따라서 프로그램 시작 시 생성되고 종료 시 해제된다.

정적변수 static도 data 영역을 사용합니다.
그런데 이 static의 위치에 따라 의미가 달라진답니다.

대표적으로 3가지 경우가 있는데,
1. 함수 내에 선언된 경우
2. 전역변수로 선언된 경우(분할 구현 시 사용)
3. 클래스 안에 선언된 경우(분할 구현 시 사용)

... 하나씩 살펴보도록 하겠습니다.

1. 함수 내에 선언된 경우

void A()
{
	static int a = 0;
    ++a;
}

int main()
{
	A();
}

정적으로 선언된 변수는 data 영역에 적재되어 프로그램 종료 시까지 남아있습니다.
그렇다면 전역변수와의 차이는 무엇이냐,
변수가 선언된 함수에서만 접근 가능합니다.
main함수에서는 a라는 변수를 사용할 수 없다는 말입니다.
이렇게 되면 나중에 변수가 무방비하게 변경될 일이 없어지겠죠?
(아 물론 포인터로 주소를 가리키면 가능합니다.)

아, 참고로 여러 번 호출이 되도 static은 한 번만 초기화 됩니다.
따라서 0에서 1,2,3.. 호출되는 수만큼 증가합니다.

2. 전역변수로 선언된 경우

test1.cpp

static int a = 0;

test2.cpp

static int a = 0;

선언된 파일을 기준으로 int a = 0;을 사용할 수 있습니다.
두 파일에 static 없이 그냥 int a = 0; 을 사용하면 링크 과정에서 오류가 납니다.
(다른 cpp에 똑같은 이름의 전역변수가 있을 때 - 전역 변수는 이때 오류가 남)
각각 파일의 전역변수로 사용이 된다는 겁니다.

3. 클래스 내부에 선언된 경우

클래스 멤버변수(함수) 앞에 static이 붙은 것을 말합니다.

class TestClass
{
private:
	static int m_StaticMember;
    int 	   m_Member;
    
public:
	TestClass()
    	// : m_StaticMember(0) -> 오류 발생함
        : m_Member(0)
    {}
   ~TestClass()
   	{}
}

정적멤버는 data 영역을 사용합니다.
그런데 객체를 생성할 때마다 계속 생성되는 걸까요?
아니요. data 영역에 한 개만 존재합니다.
객체가 만들어지기 전에 이미 존재하고 있습니다.
그럼 멤버에서 static을 사용하면 무슨 효과가 있느냐,
위 클래스에서만 사용할 수 있는 static 변수입니다.
보통 우리가 객체를 여러 개 만들면 그 지역변수와 값을 바꿔주게 되는데,
static은 그 클래스의 단 하나의 변수로서 사용이 됩니다.

보통 클래스는 헤더파일에 정의가 되는데,
그럴 때마다 static 변수가 좀 문제가 되지 않을까요?
extern과 같이 전방선언 개념입니다.
따라서 선언부가 어딘가 cpp에 존재해야합니다.

정적 멤버함수는 정적 멤버변수에 접근할 수 있음
으아아ㅏ아

0개의 댓글