본문 바로가기
c++/기초

c++ 기초 - static 변수 및 함수, 정적 지역 객체

by 농사짓는 도동 2024. 2. 5.

static 변수

클래스 내부에 멤버 변수로 선언하면 각 객체 별로 메모리에 고유한 공간을 할당받고, 객체마다 사용하는 고유한 변수가 되었다. (즉, 같은 클래스라해서 같은 변수를 공유하는 개념은 아니었다.)
 
한편, 전체 객체가 공유해서 사용해야 하는 상황에는 어떻게 해야할까? 예를 들어, 게임에서 특정 몬스터의 방어력을 전체로 낮추는 경우를 생각해보자. 각 객체별로 방어력에 접근해 낮추기 보다는 클래스(설계도)를 공유하는 모든 객체가 공유하는 변수가 필요하게 된다! 이때 바로 static 변수를 사용하게 된다.
 
static 변수는 특정 객체에 종속적으로 사용되는 것이 아니라 클래스 전체가 사용하는 개념이다. 

class Monster
{
public:
	// 멤버 변수 => 특정 객체에 종속적
	int _hp;
	// 클래스 자체와 연관
	static int s_defense;
}

 
메모리 상에는 어떻게 저장될까?

각 객체는 멤버 변수만큼의 공간을 각자 가지게 된다. 한편, static으로 정의한 변수는 메모리 상 별도의 공간에 저장되어 있으며 공용으로 해당 메모리 공간을 사용하게 된다. (여러 객체가 생성되어도 static 변수로 정의한 변수는 딱 하나만 메모리 공간에 저장되는 것이다!)

+) static 변수는 메모리 중 데이터 영역에 저장되머 초기화를 한다면 .data에, 따로 초기화를 하지 않는다면 .bss 영역에 저장된다. (함수 내부에서 만들더라도 스택 영역이 아니라 데이터 영역에 올라간다.)

static 함수

전역 함수로 만들어 준 것처럼 동작하게 된다. 

static 함수 내부에서 static 변수는 수정할 수 있지만 종속적인 일반 멤버 변수를 수정하거나 멤버 함수를 호출하는 것은 불가능하다.

class Monster
{
public:
    void TakeDamage(int damage)
    {
        _hp -= damage;
    }
    
    static void SetDefense()
    {
        // _hp = 100; // 에러!
        s_defense = 10;
    }
}

int main()
{
    Monster m1;
    m1.TakeDamage(10);

    Monster::SetDefense();  
}

 

정적 지역 객체

함수 내부에서 static을 붙여 정의한 변수를 말한다.

정적 지역 객체의 생명 주기는 프로그램의 시작과 종료를 따라간다. 즉, 메모리에 항상 올라가 있다고 보면된다.
 
함수 내에서 지역 변수로 정의하면 해당 함수가 끝날 때 변수도 메모리 상에서 사라졌다. static을 붙이면 함수가 끝나도 사라지지 않고 해당 값이 메모리 어딘가 계속 남아 있는 것이다.
 
정적 지역 객체의 경우 맨 처음 함수가 호출될 때 초기화를 해주고, 그 이후에는 값을 재사용하게 된다.

 

사용 목적

일반 지역 변수와 달리 함수를 나가도 살아있는 변수이기 때문에 특정 값을 계속 유지하고자 사용하게 된다.

예를 들어 오늘 음식점 방문자 수를 세주는 프로그램을 생각해보자. 기존에 사용하던 방식대로 하면 방문자 수 변수를 계속 유지할 수가 없다. (뭔가 값을 반환해서 캐싱한 변수에 처리하는 등 별도의 처리가 필요)

int Visit()
{
    int visitorCount = 0;
    
    visitorCount += 1;
    
    return visitorCount;
}

 
다음과 같이 정적 지역 객체로 정의하게 되면 처음 값이 초기화가 한 번 일어나고 그 뒤에 함수를 호출하면 밑에 부분만 실행된다. 그래서 값을 계속 유지할 수 있게 된다.
+) 정적 지역 객체의 경우 함수 내부에서만 사용이 가능하며 외부에서 사용하려고 하면 에러가 난다!

int Visit()
{
    //정적 지역 객체
    static int s_visitorCount = 1;
    return s_visitorCount++;
}

int main()
{
    // s_visitorCount = 2; // 에러!!
}

 

 

728x90

'c++ > 기초' 카테고리의 다른 글

c++ 기초 - 벡터 (vector)  (0) 2024.02.07
c++ 기초 - 동적 할당  (0) 2024.02.05
c++ 기초 - 클래스 (생성자, 소멸자)  (0) 2024.02.04
c++ 기초 - 배열 (array)  (0) 2024.02.04
c++ 기초 - 참조형 변수  (0) 2024.02.04