개발하는 리프터 꽃게맨입니다.

[C++] static 에 대해서 본문

언어/C, C++

[C++] static 에 대해서

파워꽃게맨 2024. 1. 8. 20:19

static 키워드

static이 앞에 붙는 변수나 함수는 어떤 객체에 소속되어 있는 것이 아니라

프로그램이 시작되면 독립적인 메모리를 차지한다는 특징이 있습니다.

 

static 키워드는 변수, 클래스의 멤버 변수, 클래스의 멤버 함수에 붙일 수 있으며

저는 '접근이 제한적인 전역 변수'라고 부릅니다.

 

실제로 전역 변수와 메모리를 차지하는 형태가 비슷합니다.

 

 

메모리에는 코드, 데이터, 힙, 스택 총 4개의 영역이 존재하는데요

static 변수, 함수와 전역 변수는 동일하게 데이터 영역에 할당됩니다.

 

그런데 전역 변수와 다른 점은 전역 변수는 어디에서나 접근이 가능하다는 특징이 있지만

static 키워드가 붙은 변수나 함수는 '제한된 범위'에서만 접근이 가능합니다.

 

하나의 블럭, 하나의 네임스페이스, 하나의 클래스, 하나의 함수, 하나의 파일 내에서만 접근이 가능하죠.

 

static 변수, 함수는 프로그램 시작 시부터 끝날 때까지 오로지 1개만 존재합니다.

동일한 static 변수와 함수를 중복해서 선언 및 정의할 수 없다는 의미입니다.

 

이 코드의 결과는 어떻게 될까요?

Func의 첫 줄에서 cnt를 계속 0으로 초기화하니까 정답은 0일까요?

 

출력은 10입니다.

 

static 변수는 한 번 초기화를 하면 이미 선언되고 데이터 영역에 독립적인 메모리를 할당했으므로

더 이상 초기화되지 않습니다.

 

이 개념은 클래스의 static 멤버 변수에서도 적용됩니다.

 

이 코드의 출력 결과는 어떻게 될까요?

static 에 대한 이해가 있으면 출력 결과는 2, 2 가 나온다는 것을 알아차려야 합니다.

 

static int ObjectId의 경우 코드 영역에 딱 1번 선언됩니다.

그렇기 때문에 관련된 개체를 생성한다고 해도 ObjectId의 메모리는 단 1개인 거죠.

단 1개의 메모리를 모든 Object 이하의 개체들을 돌려서 사용하고 있는 겁니다.

 

이제 다시 static의 특징을 알아볼까요?

1) 데이터 영역에 단 한 번만 선언된다.

2) 제한된 접근이 허용된다.

 

이제 어느 정도 static에 대한 흐름을 잡았다고 생각하고

static을 활용하는 여러 가지 예시를 보여드리겠습니다.

 

static 키워드를 활용하는 예시

1. static 전역변수

만약, 아래와 같은 코드가 있다고 가정합니다.

ExternText.h 헤더파일
ExternText.cpp 파일

 

파일 분할을 하여 구현할 때, 헤더파일의 전역 변수를 cpp 파일에 사용하고 싶을 때

위와 같은 방법으로 extern 키워드를 사용합니다.

 

그러면 'ExternText.h'를 include 한 모든 파일은 Gid 변수를 사용할 수 있게 됩니다.

 

그런데, 우리는 그저 헤더, cpp 파일에서만 사용하고 싶지 다른 파일에는 알려주고 싶지 않은 경우도 있지 않습니까?

이때 사용하는 것이 static 전역변수입니다.

 

ExternText.cpp 파일

이런 식으로 cpp 파일에 static int로 정의해 주면

static의 특징 때문에, 다른 파일에서 extern 변수인 GId에 접근하지 못합니다.

 

static 전역 변수를 사용하면 오로지. cpp,. h에서만 접근할 수 있는 전역변수를 만들 수 있습니다.

 

2. static 멤버 변수

정적 멤버 변수는 클래스당 하나의 메모리만 할당됩니다. 

각 개체마다 변수가 생기는 것이 아니라는 것을 이해하는 게 중요합니다.

 

 

예를 들어, 이런 식으로 최상위 Object 클래스에 전역 멤버 변수를 두고

생성자에서 ObjectCnt를 +1 씩 증가하도록 설계하면,

현재 몇 개의 개체를 생성했는지 파악하기 좋습니다.

 

3. static 멤버 함수

정적 멤버 함수를 사용하면 굳이 개체를 생성하지 않고도 함수에 접근할 수 있게 됩니다.

 

 

main 함수를 보면 굳이 개체를 생성하지 않아도

정적 함수인 PrintCnt를 호출하는 모습을 볼 수 있습니다.

 

단, 정적 함수에서 정적 멤버 변수를 조작하는 것은 허용이 되지만

정적 함수에서 비정적 멤버 변수, 함수를 조작하는 것은 허용되지 않습니다.

 

그렇기 때문에 TestFunc() 함수가 컴파일 에러가 나는 것입니다.

 

4. static의 특성 활용! 싱글톤 패턴

 

싱글톤 패턴은 static의 특성을 이용해서

개체를 만들지 않고 단 하나의 static 개체를 선언하여

하나의 프로그램 내에서 공통적으로 쓰이는 자원을 관리, 저장하는 역할을 구현할 때 사용되는 패턴입니다.

 

싱글톤 패턴을 사용하면, 하나의 클래스로 자원을 관리하기 굉장히 편리합니다.

GetInstance라는 함수하나로 class의 내부 static이 아닌 변수와 함수들까지 접근이 가능하다는 것이 큰 장점인 것 같습니다.

 

오늘은 싱글톤에 대해서 이 정도만 설명하고 자세한 것은 새로운 포스팅으로 찾아뵙겠습니다.

 

'언어 > C, C++' 카테고리의 다른 글

[C++] 템플릿 기본  (0) 2024.01.15
[C++] 예외처리  (1) 2024.01.09
[C++] 인라인 함수  (1) 2024.01.08
[C++] 캐스팅 4총사  (1) 2024.01.08
[C++] 다형성  (0) 2024.01.07