박하의 나날

[23] 템플릿과 자주 사용되는 컨테이너들

프로그래밍/Unreal

컴파일 하는 시점에 크기를 알수 없는 새로운 배열을 만들려면 동적 메모리 할당을 사용해야한다.

ex) int* array = new int[항목 갯수];

new[] 동적할당은 나중에 delete[ ] 를 호출해야 하는데 이런 식으로 메모리를 관리하는 것은 매우 힘들다

=> 동적메모리 할당과 해제를 자동으로 관리하는 컨테이너(C++ 객체 종류)

UE4도 컨테이너를 몇 가지 제공한다.

 

템플릿 컨테이너에는 UE4의 컨테이너, C++ 표준 템플릿 라이브러리(STL) 컨테이너 두가지가 있다.

UE4 컨테이너 : 게임 성능을 위해 작성, 컴파일 할 때 크로스 컴파일 문제를 겪고 싶지 않으면 추천.

C++ STL 컨테이너: 좀더 일관적인 인터페이스

 

1. 디버그 출력기능

1
2
3
if (GEngine){
        GEngine->AddOnScreenDebugMessage(030.f, FColor::Red, "Hello");
    }
cs

컴파일하고 실행하면 상단왼쪽 가장자리에 디버그 텍스트가 뜬다.

GEnign객체가 결과를 디버깅하는 시점에만 존재하는것 주의.

 

2. TArray<T>

TArray는 UE4버전의 동적배열이다.

<T>옵션은 배열에 저장된 데이터의 종류가 변수라는 것을 의미한다.

ex) int 배열은 TArray<int>, double 배열은 TArray<double>

 

2_1.

동적으로 크기를 변경할 수 있고, 요소들은 배열이 생성된 후에도 배열 끝에 추가할 수 있다.

 

 1

10 

20 

 

1
2
3
4
5
6
//선언
TArray<int> array;
//추가
array.Add( 1 );
//배열에 삽입 : array.Insert(값, 위치)
array.Insert(302);
cs

array.Insert를 사용해서 2라는 위치에 값을 넣으면 그 뒤의 값들은 한칸씩 밀려난다.

ex) | 1 | 10 | 5 | 20 | ----> | 1 | 10 | 30 | 5 | 20 |

 

2_2.

TArray 변수의 요소는 두 가지 방법을 통해 순차적으로 접근할 수 있다.

1
2
3
4
5
6
7
8
9
10
//1. for루프 : 정수를 사용하여 배열의 요소에 접근하는 방식
for(int index = 0; index< array.Num(); index++){
    GEgine->AddOnScreenDebugMessage( index, 30.f, FColor::Red, FString::FromInt(array[index]));
}
 
//2. 반복자
int count = 0;
for(TArray<int>::TIterator it = array.CreateIterator(); it; ++it){
    GEngine->AddOnScreenDebugMessage( count++30.f, FColor::Red, FString::FromInt( +it));
}
cs

반복자는 배열 내부의 포인터이다. 배열 내부의 값을 읽거나 변경할 수 있다.

 

++연산을 수행하면 반복자는 다음요소를 가리키게 이동한다.

순서대로 접근해야 하는 모음에 적합하다.

TArray<int> 차례대로 접근하려면 TArray<int>::TIterator형식의 반복자가 필요하다.

*을 사용하여 반복자 뒤의 값을 볼수 있다 -> 역참조

반복자를 역참조한다  =  반복자의 값을 본다는 것

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
ATArraysGameMode::ATArraysGameMode(){
    TArray<int> array;
    array.Add(1);
    array.Add(10);
    array.Add(5);
    array.Add(20);
    array.Insert(90);
    array.Insert(302);
    if (GEngine){
        for (int index = 0; index < array.Num(); index++){
            GEngine->AddOnScreenDebugMessage(index, 30.f, FColor::Yellow, FString::FromInt(array[index]));
        }
    }
}
cs

결과: 

 

2_3.

1
2
//TArray에 요소가 있는지 찾기
int index = array.Find( 10 ) ;
cs

 

3. TSet<T>

TSet<int> 변수는 정수들을 저장하고 TSet<String>은 문자열들을 저장한다.

TSet과 TArray의 차이점은 TSet은 중복 값을 허용하지 않는다는 것.

TSet 내의 모든 요소는 각자 다른값을 가지도록 되어있다.

1
2
3
4
5
6
7
8
TSet<int> set;
//추가
set.Add(1);
//순차접근 : 반복자
int count = 0;
for(TSet<int>::TIterator it = set.CreateIterator(); it; ++it){
    GEngine->AddOnScreenDebugMessage( count++30.f, FColor::Red, FString::FromInt( +it) );
}
cs

TSet에 같은 값이 중복으로 들어갈수 없고 항목에 TArray와 같이 숫자가 매겨지지 않은점 주의.

대괄호를 사용하여 요소에 접근할 수 없다->TSet 배열의 내부를 보기 위해서는 반복자를 써야만한다.

3_1.

1
2
3
4
5
6
7
8
9
10
11
12
13
TSet<int> x;
x.Add(1);
x.Add(2);
x.Add(3);
 
TSet<int> y;
y.Add(2);
y.Add(4);
y.Add(6);
//교집합
TSet<int> common = x.Intersect(y); //2
//합집합
TSet<int> uni = x.Union(y); //1,2,3,4,6
cs

두 TSet배열의 교집합의 요소가 들어있는 새로운 TSet배열이 나온다.

요소 검색은 Find.

 

4.TMap<T, S>

왼쪽에는 키를 오른쪽에는 값을 제공한다.

키 = 아이템의 이름 FString

값 = 아이템의 갯수 int

1
2
3
4
TMap<String, int> items;
items.Add("apples"4);
items.Add("donuts"12);
items.Add("swords"1);
cs

TMap을 순차접근하려면 반복자를 사용한다.

TArray나 TSet의 반복자와는 약간 다르다. TMap반복자는 키와 값을 동시에 가지고 있는데

it->Key를 사용하여 키에 접근할 수 있고 it->Value를 사용하면 값에 접근할 수 있다.

1
2
3
4
for(TMap<FString, int>::TIterator it = items.CeateIterator(); it; ++it){
    GEngine->AddOnScreenDebugMessage( count++30.f, FColor::Red, 
it->Key + FString(": "+ FString::FromInt( it->Vaue ) );
}
cs

 

 

'프로그래밍 > Unreal' 카테고리의 다른 글

0607/그냥정리  (0) 2017.06.07
[24]템플릿과 자주 사용되는 컨테이너들_2  (0) 2017.06.06
[22]npc 대화상자  (0) 2017.06.01
[21]언리얼 오브젝트 처리  (0) 2017.05.22
[20] Object  (0) 2017.05.22