[1일 1블로그 무사고 1일] Const에 대해서
Const에 대해서
const는 constant의 약자로 프로그래밍 언어에서 대상을 지정하면 그 대상은 변하지 않음을 의미하는 키워드로 쓰인다.
게임 개발을 하면서 특히, 언리얼 C++ 프로그래밍을 하면서 변수들에 Const가 많이 붙어있는 것을 볼 수 있다.
const의 위치가 제각각이어서 위치에 따라 의미가 달라지기도 하는데, 이 점이 좀 헷갈리는 것 같아 포스트로 정리하려 한다.
const 변수
1
2
3
4
5
6
7
8
9
10
11
12
int value = 5;
const int const_value = value;
int const const_value2 = value;
cout << const_value << endl;
value = 10;
cout << const_value << endl;
const_value = 3; // 컴파일 에러
const int value; // 컴파일 에러
다음과 같이 const로 선언한 변수는 런타임에서 변경할 수 없다.
const int나 int const나 똑같은데 보통 const가 타입 앞에 온다.
const_value를 value 값으로 할당하고 value의 값을 바꾸어도 처음 value값인 5가 두 번 출력된다.
const_value의 값을 바꾸면 컴파일 에러가 난다. const로 변수를 선언할 때 초기화를 안해주면 컴파일 에러가 난다. 당연한 이야기겠지만
const 멤버 변수
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class A
{
const int val;
A() : val(0)
{
}
};
class B
{
const int val;
B()
{
val = 0; // 에러
}
};
클래스에 있는 멤버 변수에 const 멤버 변수가 있어도 아직 메모리 할당이 안된 상태라 에러가 나지 않는다
여기서 A랑 B가 다른데 생성자 부분이다.
A는 val을 0으로 초기화하는데 초기화 리스트를 이용해서 초기화하고 B는 생성자 함수 내에서 초기화한다.
보통 초기화 리스트를 이용해 const 멤버 변수를 초기화해주는데 B처럼 생성자 함수 내에서 초기화하게 되면 const int val;로 선언을 한 다음 val = 0;을 하는 꼴이라 컴파일 에러가 난다
const 포인터 변수
포인터 변수의 경우 const의 위치가 중요하다
1
2
3
4
5
6
7
8
9
10
11
int val = 3;
int val2 = 6;
const int* ptr = &val;
int* const ptr2 = &val;
*ptr = 4; // 컴파일 에러
*ptr2 = 5;
ptr = &val2;
ptr2 = &val; // 컴파일 에러
const가 타입 앞에 있을 때(ptr)는 ptr이 가리키고 있는 값 자체는 바꿀 수 없다. 하지만 ptr이 가리키는 주소는 바꿀 수 있다.
반대로 const가 타입과 변수 이름 사이에 있다면 ptr이 가리키고 있는 값 자체는 바꿀 수 있지만 ptr2가 가리키는 주소는 바꿀 수 없다.
즉, ptr은 상수 타입의 변수(const int)를 가리키는 포인터고 ptr2는 int를 가리키는 포인터 자체가 상수가 된거라 포인터 값(주소)을 바꿀 수 없다
그래서 const를 타입 앞 뒤에 다 쓴다면 포인터가 가리키는 값도 못 바꾸고 포인터의 값도 못 바꾸는 포인터가 된다
const 멤버 함수
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int Func() const; // 컴파일 에러
class A
{
int val = 0;
int Func() const
{
int a = 1; // 지역 변수는 변경 가능
a++;
val++; // 컴파일 에러
return val;
}
};
const 멤버 함수는 class 내의 멤버 함수만 const화한다.
const의 위치가 함수 선언문 맨 뒤에 있는데 이는 즉 해당 멤버 함수 내에서는 이 클래스의 멤버 변수(val)을 상수화 시킨다는 의미이다.
즉 멤버 변수 val의 값은 변경하지 못하고 지역 변수 a는 변경이 가능하다는 점
언리얼을 하면서 굉장히 많이 본 const 꼴이니까 외워 두자!