Ch1-3. Bulls & Cows : 멤버 변수, FString::Printf
카테고리: UE4Cpp1
태그: Cpp UE4 Game Engine
Udemy에 있는 Unreal Engine C++ Developer: Learn C++ and Make Video Games 강의를 듣고 정리한 필기입니다. 😀
Chapter 1. Bulls & Cows 게임 만들기
컴파일 안하고 플레이를 눌러버리면 이전 C++ 코드로 플레이된다. 컴파일 소요 시간이 좀 있어서
🚀 멤버 변수
FString HiddenWord = TEXT("cake"); // Move outside this function
void UBullCowCartridge::BeginPlay() // When the game starts
{
Super::BeginPlay();
// Setting Up Game
SetUpGame();
// ...
}
void UBullCowCartridge::OnInput(const FString& Input) // When the player hits enter
{
// ...
}
void UBullCowCartridge::SetUpGame()
{
// ...
}
- 위와 같이
FString HiddenWord = TEXT("cake");
를 📜BullCowCartridge.cpp 전역에서 사용할 변수를 📜BullCowCartridge.cpp 전역 변수로 선언한다면?- 클래스의 멤버변수로서가 아닌, 이렇게 cpp 파일 위에다가 일반 전역 변수로 선언해버린다면 생길 수 있는 문제점
- 만약 이 📜BullCowCartridge.cpp 파일이 두 개의 액터에 붙어 두 cpp 파일이 실행됐다고 가정했을 때, 하나의 액터에서 만약 이
HiddenWord
변수 값을 바꿔버린다면 다른 액터에서도 이 바뀌어 버린HiddenWord
변수 값을 사용하게 된다. - 만약 이런 변수들이
hp
,coolTime
이런거라면 문제가 생길 수 있다.
- 만약 이 📜BullCowCartridge.cpp 파일이 두 개의 액터에 붙어 두 cpp 파일이 실행됐다고 가정했을 때, 하나의 액터에서 만약 이
- 따라서 각각의 인스턴스마다 따로 메모리를 가져 관리될 수 있도록 클래스의 멤버 변수로서 선언을 해야 한다. cpp 파일의 클래스 바깥의 일반 전역 변수로서 선언해버리면 공유가 될 수 있기 때문에 문제가 생길 수 있다.
- 클래스 전역, 즉 동일한 인스턴스 범위 내에서의 멤버 함수들에서 접근할 수 있도록 클래스 멤버 변수로 선언해야 한다.
- 클래스의 멤버변수로서가 아닌, 이렇게 cpp 파일 위에다가 일반 전역 변수로 선언해버린다면 생길 수 있는 문제점
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class BULLCOWGAME_API UBullCowCartridge : public UCartridge
{
GENERATED_BODY()
public:
virtual void BeginPlay() override;
virtual void OnInput(const FString& Input) override;
void SetUpGame();
// Your declarations go below!
private:
FString HiddenWord; // Move outside this function.
int32 Lives;
};
FString HiddenWord;
요렇게 헤더파일의 클래스 멤버 변수로 넣어주는게 좋다. 인스턴스마다 별개의 메모리로 따로 관리될 수 있도록..
🚀 함수
- 함수는 코드의 재사용성을 높여준다.
- 하나의 함수가 하나의 일만 담당하도록 하는 것이 좋다.
- 함수의 이름이 함수가 하는 일을 대표할 수 있도록 짓는 것이 좋다.
- 디버깅이 편하고 구분이 쉬워지기 때문!
- 함수의 이름이 함수가 하는 일을 대표할 수 있도록 짓는 것이 좋다.
- cf) 언리얼은 컴파일 시간이 좀 느린 편이다.
- 컴파일 시간 줄이는 방법 나중에 프로그램 규모가 커지면 찾아보기
🚀 찾기 바꾸기
비주얼 스튜디오 편집에서 원하는 범위 내에(현재 문서 혹은 현재 프로젝트 혹은 전체 솔루션) 검색하고 검색된 전체 결과를 원하는 문구로 바꿀 수가 있다.
🚀 FString::Printf
PrintLine(FString::Printf(TEXT("The HiddenWord is: %s. \nIt is %i characters long"), *HiddenWord, HiddenWord.Len()));
PrintLine(FString::Printf(TEXT("The HiddenWord is: %s."), *HiddenWord));
- 참고로 PrintLine 은 그냥 📜Catridge.cpp로부터 상속 받은, 터미널 액터에 문자열을 출력되도록 정의한 사용자 지정 멤버 함수다. 언리얼 자체 함수 아님.
FString
클래스의Printf
함수는- 형식 지정자로 새롭게 조립한
FString
을 리턴하는 것 뿐만 아니라%s
,%i
,%.3i
등등..
- C언어의 printf 처럼 화면에 출력시킬 수도 있다.
- 형식 지정자로 새롭게 조립한
- Printf 에 FString 을 넘길 땐 %s로 받는 경우 반드시 * 를 붙여 주소로 넘겨야 한다.
*
을 붙여주지 않으면 컴파일 에러가 발생한다.%s
는TCHAR *
포인터 타입을 받기 때문이다. (TCHAR 타입의 배열의 첫번째 원소의 주소. C에서char *
를 받는 것과 같은 이치인 것 같다.)- ⭐
FString
클래스는TArray<TCHAR>
타입의 멤버 변수에 문자열을 저장하기 때문에,FString
클래스는*
사용시TArray<TCHAR>
즉,TCHAR *
배열의 주소를 리턴하도록*
연산자를 오버로딩이 되어 있다.// FString 클래스 내부 typedef TArray<TCHAR> DataType; DataType Data; // TArray<TCHAR> Data 와 같다. 생성자를 통해 여기에 문자열을 저장한다. //... FORCEINLINE const TCHAR* operator*() const { return Data.Num() ? Data.GetData() : TEXT(""); }
- ⭐
FString
도 내부적으론(멤버 변수로) 문자열을TCHAR
원소들로 이루어진 배열로서 저장하고 있고 마찬가지로 마지막 원소 다음에 null character\0
를 붙여 저장한다.
Tip 비주얼 스튜디오에서 우클 - 정의로 이동 할 필요 없이
Ctrl
누른체로 해당 함수나 연산자를 누르면 바로 정의로 이동한다.
Len
FString HiddenWord = TEXT("cake");
PrintLine(FString::Printf(TEXT("It is %i characters long"), HiddenWord.Len())); // 4 출력
문자열의 길이를 리턴
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기