Unreal5/Unreal C++
[U C++] const 선언
taene_
2024. 7. 8. 17:55
const 변수
1. const 비-멤버 변수
const int num = 1; // 일반적인 표현
int const num = 1; // 위와 같은 의미
num = 2; // Compile Error
- 위와 같이 선언하면 num은 변경할 수 없는 변수인 상수가 된다.
- 또한 함수의 반환형이나 매개변수가 const 변수형일 때도 같은 의미이다.
2. const 멤버 변수
class Foo
{
const int num; // 메모리 할당이 아님
Foo(void)
: num(1) // const int num = 1;
{}
};
class Bar
{
const int num;
Bar(void)
{
num = 1; // Compile Error
// const int num;
// num = 1;
}
};
- const 변수는 반드시 선언 시 초기화를 해야 한다.
- class의 멤버 변수를 const로 선언 시에는 반드시 초기화 리스트를 사용해서 초기화를 해줘야 한다.
3. const 포인터 변수
int num = 1;
const int* ptr = # // *ptr 상수화
*ptr = 2; // Compile Error
num = 2; // Pass
- 첫번째, const 위치가 맨 앞에 있으면서 포인터 변수가 가리키는 값에 대해서 상수화를 시키는 경우
- 포인터 변수가 가리키는 num 자체가 상수화가 되는 것이 아니므로 num 값을 바꾸는것은 된다.
int num1 = 1;
int num2 = 2;
int* const ptr = &num1; // ptr을 상수화
ptr = &num2; // Compile Error
- 두번째, const 위치가 type과 변수 이름 사이에 있으면서 포인터 변수 자체를 상수화 시키는 경우
- 포인터 변수는 대상의 주소 값을 저장하는 변수인데, 위의 ptr은 자기 자신을 상수화 시키는 것이기 때문에 num2의 주소 값으로 변경하려고 하면 에러가 발생한다.
// 위의 두 경우를 모두 사용하는 형태
int num = 1;
const int* const ptr = #
const 멤버 함수
int GetString(void) const; // Compile Error
class Foo
{
int num = 1;
int GetNum(void) const
{
int a = 1;
a++; // 지역 변수는 가능하다
num++; // Compile Error
return num;
}
};
- const 멤버 함수는 class의 멤버 함수만 const로 상수화를 시킬 수 있고 비-멤버 함수는 const 함수로 선언이 불가능하다.
- const의 위치는 함수 선언문 맨 뒤이고, 해당 멤버 함수 내에서 모든 멤버 변수를 상수화시킨다는 의미이다. 따라서 위와 같이 멤버 변수인 num은 변경할 수 없고 지역 변수인 a는 변경할 수 있다.
const 멤버 함수에 관하여
FORCEINLINE const FString& GetName() const { return Name; }
FORCEINLINE class UCard* GetCard() const { return Card; }
- 첫 번째 코드에서 GetName 함수는 const 멤버 함수이기 때문에 Name 멤버 변수에 대한 변경을 허용하지 않는데, 반환값이 const FString& 형식이어야만 이를 보장한다. 질문에 있는 대로, FString&로 반환할 경우 호출자가 반환된 참조를 통해 Name을 변경할 수 있기 때문에 컴파일러는 오류를 발생시킨다.
- 두 번째 코드에서 GetCard 함수는 포인터를 반환하는데, 여기서 중요한 것은 반환되는 UCard* 포인터 자체는 const 함수인 ‘GetCard’에서 변경할 수 없다. 그러나 이 포인터가 가리키는 객체, 즉 UCard 객체는 const가 아니기 때문에, 반환 후에 객체의 상태를 변경할 수 있는 가능성이 있다.
- 여기서 const 멤버 함수에서 포인터를 반환할 때, 객체의 상태 변경을 전혀 허용하지 않으려면 반환 타입을 const UCard*로 지정해야 한다. 이렇게 반환 타입에 const를 붙이면 포인터를 통해 원본 객체를 변경하는 것이 금지된다.
FORCEINLINE const class UCard* GetCard() const { return Card; }
- 이 경우 GetCard의 반환값을 통해 UCard 객체의 변경이 불가능하다는 것을 보장할 수 있다.