우선, #include "__.h"를 사용하는 것은 해당 헤더의 소스 코드 전체를 include문의 위치에 그대로 복사 & 붙여넣기하는 것과 같다.
컴파일 시에 소스 코드의 include문이 해당 헤더 파일 전체로 교체되는 것이다.
주의: 헤더에 헤더를 include하는 것은 가급적 피하는 것이 좋다.
- 헤더 파일의 비대화
- 헤더파일은 기본적으로 다른 여러 소스코드에서 include되어서 사용된다.
- 만약 자기 자신이 아닌 다른 헤더를 include하는 헤더가 있다면, 그 헤더를 include하는 것은 그 헤더 뿐만이 아니라 그 헤더가 포함하고 있는 다른 헤더까지 include하는 것과 같다.
- 예를 들어, Item.h에서 Character 타입 변수를 사용하기 위해 #include "Character.h"를 사용한다고 하자.
- 그런데 Character.h가 캐릭터 기능에 필요한 다른 여러 헤더 파일 (Weapon.h, Inventory.h, ...) 등을 include하고 있다면,
- Item.h에서 #include "Character.h"를 하는 것은 Weapon.h, Inventory.h, ...까지 모두 include하는 것이다.
- 이는 헤더의 비대화로 이어지고, 컴파일 성능을 크게 악화시킨다.
- 두 헤더 include의 무한루프
- 두 헤더파일 HeaderA.h, HeaderB.h가 있다고 가정하자.
- 그리고, 각각의 헤더는 #include <HeaderB.h>, #include <HeaderA.h>로 시작한다고 가정하자.
- 이 상태로 컴파일을 한다면, 먼저 HeaderA에서 HeaderB를 include하므로 HeaderB를 그대로 #include <HeaderB.h> 문의 위치로 가져온다.
- 가져온 HeaderB.h는 #include <HeaderA.h>로 시작하므로, 이번엔 그 위치에 HeaderA.h를 그대로 가져온다.
- 가져온 HeaderA.h는 #include <HeaderB.h>로 시작하므로, 이번엔 그 위치에 HeaderB.h를 그대로 가져온다.
- 상술한 과정이 무한히 반복되면서, 컴파일이 제대로 이루어질 수 없다. (컴파일 에러 발생)
- 프로젝트의 규모가 커질수록, 이 같은 문제가 암시적으로 일어나기 쉽다.
따라서, 언리얼 엔진 프로젝트에서는 헤더를 include할 때 .h(헤더)이 아닌 .cpp(구현 코드)에서 하는 것이 바람직하다.
- 다만, 부모 클래스의 헤더를 포함하는 것은 괜찮다. 슈퍼클래스의 함수를 override하는 등의 일을 하려면 불가피하며, 상술한 무한루프의 문제가 나타날 가능성이 없기 때문이다.
- struct 헤더를 포함하는 것도 괜찮다. 일반적으로 구조체는 클래스에 비해 크기가 상대적으로 작아, 헤더 파일의 비대화가 잘 일어나지 않는다.
하지만, 헤더 파일에서 해당 클래스 타입의 변수를 써야할 때는? → 포워드 선언을 사용하도록 한다.
- 포워드 선언에는 두 가지 방법이 있다.
- 사용하고자 하는 외부 클래스 타입 변수를 선언할 때, 앞에 'class' 키워드 붙이기
- 클래스 본문 위에 'class (외부 클래스 이름)' 작성
- 포워드 선언은 실제로 클래스 전체를 include하는 것이 아닌, 그 타입의 이름을 임시로 사용하겠다는 의미이다.
- 따라서 해당 클래스 타입을 자유롭게 사용하는 것은 불가능하지만, 해당 타입의 포인터를 선언하는 것이 가능하다.
- 결과적으로 헤더 파일에서는 포워드 선언을 통해 포인터만 만들어두고, .cpp파일에서 해당 포인터에 값을 할당해서 사용할 수 있다.
- 또한 .cpp파일에서는 헤더 파일의 include함으로써 해당 타입의 실제 변수를 생성하거나, 함수의 매개변수나 리턴 타입으로 설정하는 등 다양한 작업을 할 수 있다.
추가로, 꼭 헤더에서 include하고 싶은 외부 클래스의 어떤 부분이 있다면, 그것만 .h파일로 따로 분리해내어 해당 헤더를 include하는 것도 좋은 방법이다.
'언리얼 엔진 5 > 공부' 카테고리의 다른 글
[언리얼 엔진 5] 애니메이션 사운드 (0) | 2023.12.16 |
---|---|
[언리얼 엔진 5] Blend Space 방향 전환이 부자연스러울 경우 확인할 것 (0) | 2023.12.15 |
[언리얼 엔진 5] Collision에 대하여 (0) | 2023.11.27 |
[언리얼 엔진 5] Input Action에 대하여 (0) | 2023.11.27 |
[언리얼 엔진 5] CDO(Class Default Object)에 대하여 (0) | 2023.11.27 |