목차
- 01. Intro
- 02. static 키워드
- 지역 변수에서 사용
- 전역 변수에서 사용
- 클래스 멤버 변수에서 사용
- 클래스 멤버 함수에서 사용
- 전역 함수로 사용
- 03. 마무리
- 04. 연관 내용
01. Intro
오늘은 [static] 키워드에 대해 알아보겠습니다.
02. static 키워드
static 키워드는 변수, 함수 또는 클래스 멤버로 사용할 수 있습니다.
static 키워드를 어디에 사용하냐에 따라 서로 다른 역할을 가지게 됩니다.
하나씩 자세히 보도록 하겠습니다.
지역 변수에서 사용
특징
클래스가 아닌 함수 내에서 지역 변수에 static 키워드를 붙이면, 해당 변수는 한 번만 초기화됩니다.
따라서, 프로그램 종료될 때까지 이전 값을 유지합니다.
즉, 함수가 처음 호출될 때, 한 번만 초기화되고, 이후에는 초기화를 하지 않아 값을 유지합니다.
코드 예시
#include <iostream>
using namespace std;
void doSomething()
{
// static 지역 변수
static int count = 0;
count++;
cout << "count : " << count << endl;
}
int main()
{
// count : 1
doSomething();
// count : 2
doSomething();
// count : 3
doSomething();
// count : 4
doSomething();
// count : 5
doSomething();
}

위 코드를 실행했을 때, count 변수가 한 번만 초기화되고 이전 값이 계속 유지되는 것을 확인할 수 있습니다.
함수를 호출할 때, 지역 변수가 포함된 스택 프레임이 생성되어 콜 스택에 누적됩니다.
그리고, 함수가 종료되면, 해당 함수의 스택 프레임이 제거됩니다.
( 실제로는 스택 포인터만 위치가 바뀌어 메모리에 저장된 값이 초기화되지 않음. )
![]() |
![]() |
위 논리를 따랐을 때, static 지역 변수도 지역 변수의 일종이니깐 스택 프레임이 저장되는 스택 영역에 있다고 생각할 수 있습니다.
하지만, 위 사진처럼 메모리에서 확인한 결과, count의 메모리 주소는 항상 고정이 되어 있습니다.
따라서, static 지역 변수는 스택 영역에 저장되어 있지 않습니다.
static 지역 변수는 데이터 영역에 저장되어 있습니다.
여담으로, 데이터 영역에는 전역 변수나 static 변수처럼 프로그램 실행 중에 항상 유지되어야 하는 변수들이 저장됩니다.
사용 이유
1. 상태 유지 : 재귀 함수에서 상태를 유지할 수 있으므로, 캐싱이 필요한 정보에 대해 static 지역 변수를 사용합니다.
2. 카운터로 사용 : 카운터처럼 함수 호출 횟수 등으로도 사용할 수 있습니다.
전역 변수에서 사용
특징
전역 변수에 static 키워드를 붙이면, 해당 전역 변수는 현재 선언된 파일 내에서만 접근 가능하도록 접근 범위를 제한합니다.
따라서, extern 키워드를 통해 다른 파일에서 현재 파일의 static 전역 변수에 대해 접근할 수 없습니다.
사용 이유
1. 캡슐화 효과 : 전역 변수이지만, 다른 파일에서 접근이 불가능하도록 제한합니다.
2. 이름 충돌 방지 : 같은 이름의 전역 변수를 여러 파일에서 선언이 가능합니다.
static 키워드를 사용하지 않은 전역 변수인 경우, 여러 파일에서 같은 이름으로 여러 번 선언하면, 컴파일 시 오류가 발생합니다.
링커가 정확히 어느 전역 변수를 참조해야 하는지 모르기 때문에, 중복 정의로 인한 링커 오류가 발생합니다.
이를 방지하기 위해, static 키워드 전역 변수를 사용합니다.
클래스 멤버 변수에서 사용
특징
클래스 내에서 static 멤버 변수는 다음과 같은 특징을 가지고 있습니다.
1. 모든 클래스의 객체가 static 멤버 변수의 값을 공유하므로, 클래스당 하나만 존재합니다.
2. 객체 없이, 접근이 가능합니다. [클래스명::변수명] 형태로 접근할 수 있습니다. ( 물론, 객체를 통해서도 접근 가능합니다. )
3. 반드시, 클래스 외부에서 초기화를 해야 합니다.
코드 예시
#include <iostream>
class Sport
{
public:
// 클래스 static 멤버 변수
static int num;
};
// 외부에서 static 멤버 변수 초기화
int Sport::num = 100;
int main()
{
// 외부에서 static 멤버 변수 접근
cout << Sport::num << endl;
// Sport 클래스 객체 2개 생성
Sport sport1, sport2;
sport1.num = 300;
// sport2.num = 300을 가진 것을 확인
cout << sport2.num << endl;
}

위 코드를 실행하면, 다음과 같은 결과가 나옵니다.
코드를 한 줄씩 분석해 보겠습니다.
class Sport
{
public:
// 클래스 static 멤버 변수
static int num;
};
Sport 클래스 내에서 num이라는 static 멤버 변수를 선언했습니다.
// 외부에서 static 멤버 변수 초기화
int Sport::num = 100;
Sport 클래스 외부에서 Sport::num의 형태로 초기화를 한 번 진행했습니다.
참고로, main 함수처럼 함수 내부에서는 초기화가 불가능합니다.
불가능한 이유는 다음과 같습니다.
static 멤버 변수는 프로그램 실행 전에, 메모리에 로드되어야 합니다.
하지만, main 함수처럼 함수는 프로그램이 실행할 때 호출됩니다.
함수의 실행 시점이 static 멤버 변수의 초기화 시점보다 늦게 실행되어, main 함수처럼 함수 내부에서는 초기화가 불가능합니다.
int main()
{
// 외부에서 static 멤버 변수 접근
cout << Sport::num << endl;
}
외부에서 [클래스명::변수명] 형태로 static 멤버 변수에 접근할 수 있습니다.
int main()
{
// Sport 클래스 객체 2개 생성
Sport sport1, sport2;
sport1.num = 300;
// sport2.num = 300을 가진 것을 확인
cout << sport2.num << endl;
}
static 멤버 변수는 모든 객체가 공유하고 있으므로, sport1 객체에서 값을 변경해도, sport2 객체에서도 값이 변경된 것을 확인할 수 있습니다.
private로 선언된 static 멤버 변수
#include <iostream>
class Sport
{
public:
void setNum(const int x) { num = x; }
private:
// 클래스 static 멤버 변수
static int num;
};
// 외부에서 static 멤버 변수 초기화
int Sport::num = 100;
int main()
{
//cout << Sport::num << endl;
//Sport sport1, sport2;
//sport1.num = 300;
//cout << sport2.num << endl;
}
static 멤버 변수가 [private]으로 선언되어 있다면, 외부에서 접근할 수 없어 [클래스명::변수명] 형태를 사용할 수 없습니다.
외부에서 접근하지 못한다는 것만 제외하고, 나머지는 [public]으로 static 멤버 변수를 선언했을 때와 같습니다.
그래서, 외부에서 static 멤버 변수도 초기화를 해야 합니다.
또한, [private] 접근 지정자이므로 클래스 내부의 멤버 함수에서는 자유롭게 사용할 수 있습니다.
클래스 멤버 함수에서 사용
특징
static 멤버 함수는 static 멤버 변수처럼 객체 없이, 호출할 수 있습니다.
[클래스명::함수명]의 형태로 static 멤버 함수를 호출할 수 있습니다.
객체와 관계없이 호출할 수 있어, this 포인터가 존재하지 않습니다.
즉, 어떤 특정 객체에 속한 것이 아니라 클래스 전체에 속한 함수이므로 객체를 통해 접근할 수 있지만, 클래스에 대한 함수로 호출됩니다.
static 멤버 함수에서는 static 멤버 변수 및 다른 static 함수만 접근할 수 있습니다.
즉, 다른 클래스의 static 멤버 함수, static 전역 함수, static 전역 변수에 접근할 수 있습니다.
(물론, 다른 지역 함수도 접근할 수 있습니다.)
다만, static 지역 변수는 함수 내에서만 접근할 수 있으므로, static 멤버 함수에서 접근할 수 없습니다.
코드 예시
#include <iostream>
class Project
{
public:
static void another()
{
//
}
};
class Sport
{
public:
static void something()
{
_num = 10;
// _game = 100;
Project::another();
}
private:
static int _num;
int _game;
};
// 외부에서 static 멤버 변수 초기화
int Sport::_num = 100;
int main()
{
Sport::something();
}
위 코드를 확인하면서, static 멤버 함수에 대한 특징을 다시 보겠습니다.
class Sport
{
public:
static void something()
{
_num = 10;
// _game = 100;
Project::another();
}
private:
static int _num;
int _game;
};
1. Sport 클래스 내부의 static 멤버 변수인 _num 변수만 접근할 수 있습니다.
2. 다른 클래스인 Project의 static 멤버 함수 another도 호출할 수 있습니다.
3. static 멤버 함수를 [클래스명::함수명]으로 호출하는 것을 확인할 수 있습니다.
전역 함수에서 사용
특징
전역 함수에 static 키워드를 붙이면, static 전역 변수처럼 static 전역 함수는 현재 선언된 파일 내에서만 접근 가능하도록 접근 범위를 제한합니다.
따라서, extern 키워드를 통해 다른 파일에서 현재 파일의 static 전역 함수에 대해 접근할 수 없습니다.
사용 이유
1. 캡슐화 효과 : 전역 함수이지만, 다른 파일에서 접근이 불가능하도록 제한합니다.
2. 이름 충돌 방지 : 같은 이름의 전역 함수를 여러 파일에서 선언이 가능합니다.
static 키워드를 사용하지 않은 전역 함수인 경우, 여러 파일에서 같은 이름으로 여러 번 선언하면, 컴파일 시 오류가 발생합니다.
이는, static 전역 변수와 동일한 원리로 인해서, 발생하는 오류입니다.
03. 마무리
오늘은 static 키워드에 대해서 알아봤습니다.
용도별로 static 키워드를 사용했을 때, 특징을 정리하면 아래와 같습니다.
1) 지역 변수
함수 처음 호출할 때만 초기화 (초기화는 한 번만 진행)
호출 종료되어도 값 유지
2) 전역 변수
접근 범위 제한으로 같은 파일 내에서만 접근 가능
3) 클래스 멤버 변수
클래스 외부에서 초기화 필수
모든 객체가 값을 공유
객체 유무에 상관없이 접근 가능
4) 클래스 멤버 함수
객체 없이 호출 가능
this 포인터 사용 불가능
5) 전역 함수
접근 범위 제한으로 같은 파일 내에서만 접근 가능
04. 연관 내용
읽어주셔서 감사합니다.
틀린 내용 지적은 언제나 환영입니다!
'게임 개발 > C++' 카테고리의 다른 글
| [C++] auto 키워드 (0) | 2025.03.18 |
|---|---|
| [C++] explicit 키워드 (0) | 2025.03.17 |
| [C++] 부동소수점 (0) | 2025.03.15 |
| [C++] 전방 선언 (2) | 2025.03.13 |
| [C++] 접근 지정자 (0) | 2025.03.12 |

