Publish:

태그: , ,

카테고리:


🤯 언리얼을 하기 위해 C++ 기억 되살리기 프로젝트

static 키워드

  • 범위(scope)의 제한을 받는 전역 변수
    • 실행 도중에 딱 하나만 있는 변수. 개체 별로 여러개 둘 수 있는 변수가 아님
    • 하지만 어디서나 접근 할 수 있게 하진 않음. 그래서 영역이 전역은 아님.
    • 범위의 제한을 받는 전역 변수
  • 어떤 범위?
    • 파일 속
    • 네임스페이스 속
    • 클래스 속
    • 함수 속

1. extern 키워드

  • 다른 파일의 전역변수에 접근을 가능하게 해줌
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// ExternTest.h
extern int globalValue;             // <- extern 전역 변수!

void IncreaseValue();

// ExternTest.c
#include "ExternTest.h"

int globalValue = 2;
void IncreaseValue()
{
    globalValue++;
}

// main.c
#include "ExternTest.h"             // <- ExternTest.h에 적힌 내용을 여기에 복붙해준다는 식의 의미
                                    // extern 이니 어딘가에 값이 있다는 뜻이니 빌드는 해줄게!

int main()
{
    printf("%d", globalValue);
}

2. c 스타일 static

  • 정적 변수가 함수 밖에 있다면 다른 파일에선 이 정적 변수에 접근할 수 없음
  • 내 함수 밖에선 못쓰게 범위를 제한해준다 (외부 파일에서 내 변수 접근 못하게 막는 법이었음)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// StaticTest.h
extern int globalValue;             // <- extern 키워드 사용했음!

void IncreaseValue();

// StaticTest.cpp
#include "StaticTest.h"

static int globalValue = 2;         // <- 근데 static 을 딱 붙이면, 링커 에러가 남. 
                                    // 저 변수는 static이라서 밖에서 못 쓰는 거야;;
                                    // 그래서 exe 파일 안나옴.

void IncreaseValue()
{
    globalValue++;
}

// main.cpp
#include "StaticTest.h"

int main()
{
    // 링커(Linker) 에러
    printf("%d", globalValue);
    return 0;
}

3. 함수 속 정적 변수

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void Accumulate(int number)
{
    static int result = 0;              // <- static
                                        // 보통 함수에 들어올 때 마다 지역 변수로 생성하고 버리는데,
                                        // 만드는 순간 얘는 이 함수 영역에 짱박히게 됨.
                                        // 근데 한번 이 코드가 실행되어 초기화 되면,
                                        // 다음에 또 이 함수가 호출될 땐 초기화문을 건너뛰어버림.
                                        // 그래서 result가 0 이 되는게 아님!
    result += number;
    std::cout << "result = " << result << std:: endl;
}

int main()
{
    Accumulate(10);         // 10
    Accumulate(20);         // 30
    return 0;
}
  • 함수로 범위(scope)가 제한된 전역 변수
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    void Accumulate(int number)
    {
      // 여기서부터
      static int result = 0;
      result += number;
      std::cout << "result = " << result << std::endl;
      // 여기까진 result에 접근 가능
    }
    
    int main()
    {
      // 다른 영역에선 result에 접근 불가
    }
    

4. 정적 멤버 변수

  • 각 클래스 당 하나만 존재
    • 각 개체마다 변수가 생기는 게 아님. 개체의 메모리 레이아웃에 들어가는 게 아님
  • 그래서 클래스 메모리 레이아웃에 포함
  • exe파일 안에 필요한 메모리가 잡혀 있음
  • 전역 변수 대신 정적 멤버변수를 쓸 것
    • 범위를 제한하기 위해
  • C 스타일의 정적변수르르 쓸 이유가 이제 없음
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Cat.h
class Cat
{
    public:
        Cat();
    private:
        static int mCount;
};

// Cat.cpp
int Cat::mCount = 0;        // 초기화
Cat::Cat()
{
    mCount++;
}

5. 정적 멤버 함수

  • 논리적인 범위에 제한 된 전역 함수
  • 해당 클래스의 정적 멤버에만 접근 가능
    • 접근하려 하면 컴파일 에러 남.
  • 개체가 없이도 정적 함수를 호출할 수 있음
1
2
3
4
5
6
7
8
9
10
11
// Math.h
class Math
{
    static int Square(int number);
};

// Math.cpp
int Math::Square(int number)
{
    return number * number;
}

이슈 및 공부한 것을 기록해두는 개인 블로그 입니다. 댓글, 피드백 환영합니다 🙂

Update:

댓글남기기