1. enum vs enum class (Scoped Enum)
현대 C++(C++11 이상) 및 언리얼 엔진 환경에서 enum class 사용은 선택이 아닌 필수입니다.
📋 주요 차이점 비교
| 구분 | enum (Unscoped) | enum class (Scoped) |
| 유효 범위 | 전역(Global) 범위에 노출됨 | 클래스 범위 내로 제한됨 |
| 타입 안전성 | 정수형(int)과 암시적 변환 가능 | 암시적 변환 불가 (명시적 캐스팅 필요) |
| 이름 충돌 | 다른 enum과 이름 중복 불가 | 이름 중복 가능 (Scope로 구분) |
| 메모리 지정 | 컴파일러가 결정 (불투명함) | Underlying Type(uint8 등) 지정 가능 |
💡 지식의 확장: 왜 enum class인가?
- 타입 안정성: 실수로 열거형 값을 정수 함수 인자에 넣는 치명적 버그를 컴파일 타임에 차단합니다.
- 메모리 최적화: 특히 모바일 환경에서는 enum class EState : uint8과 같이 타입을 명시하여 메모리 대역폭을 절약할 수 있습니다.
- 한계 인식: 출력 시 static_cast<int>()를 거쳐야 하는 번거로움이 있지만, 이는 대규모 프로젝트에서 '코드의 명확성'을 보장하는 비용입니다.
2. 복사 생성자 (Copy Constructor)
객체가 복사될 때 호출되는 생성자로, 특히 포인터 멤버가 있는 클래스에서 매우 중요하게 다뤄야 합니다.
⚠️ 얕은 복사(Shallow Copy)의 위험성
디폴트 복사 생성자는 포인터의 '주소값'만 복사합니다. 이로 인해 세 가지 치명적인 문제가 발생합니다.
- 중복 해제(Double Free): 두 객체가 같은 주소를 해제하려다 크래시 발생.
- 댕글링 포인터(Dangling Pointer): 한 객체가 메모리를 해제했는데 다른 객체가 그곳을 참조함.
- 의도치 않은 값 변경: 한 객체의 수정이 다른 객체에 영향을 줌.
🔄 복사 생성자가 호출되는 3가지 시점
- 기존 객체로 새로운 객체를 초기화할 때 (T a = b;)
- 함수에 인자를 값 전달(Pass by Value) 방식으로 넘길 때
- 함수에서 객체를 값으로 반환할 때 (단, 최신 컴파일러는 RVO로 최적화하기도 함)
3. 문자열 관리와 메모리 최적화
C++의 기본 문자열 처리와 언리얼 엔진의 자동화 시스템 비교입니다.
💎 깊은 복사(Deep Copy)를 통한 문자열 관리
- 직접 구현: new char[len + 1]을 통해 각 객체가 독립적인 메모리 공간을 가지도록 설계합니다.
- 언리얼 엔진(FString): 내부에 TArray<TCHAR>를 가지며, 예약 할당(Slack)을 통해 빈번한 재할당 성능 저하를 막습니다.
🚀 최적화 대안 (Unreal Engine 기준)
- FName: 해시 테이블을 사용하여 비교 연산이 O(1)입니다. 수정이 필요 없는 아이템 이름, 태그 등에 적합합니다.
- FText: 다국어 지원 및 로컬라이징이 필요한 UI 텍스트에 사용합니다.
- FString::Reserve(): 문자열이 커질 것을 미리 안다면 한 번만 할당받아 힙 파편화를 방지합니다.
4. 방어적 프로그래밍: ensure vs IsValid
런타임 안정성을 확보하기 위한 두 가지 핵심 도구입니다.
| 도구 | 성격 | 사용 목적 | 배포(Shipping) 시 |
| ensure(조건) | 디버깅용 경고 | "이곳에 Null이 오면 설계 오류다"를 알림 | 코드 증발 (성능 영향 없음) |
| IsValid(객체) | 실행 로직용 분기 | "객체가 사라졌을 수 있으니 확인 후 실행" | 항상 작동 |
Senior's Tip: 모든 곳에 if (IsValid)만 쓰면 버그가 로그 없이 묻힐 수 있습니다. 설계상 완벽해야 하는 곳엔 ensure나 check를 써서 즉시 문제를 파악해야 합니다.
5. 임시 객체(Temporary Object)와 이동 시맨틱
눈에 보이지 않는 성능 도둑, 임시 객체를 제어하는 방법입니다.
📦 임시 객체가 생성되는 이유
함수가 결과물을 반환할 때, 지역 변수는 파괴되므로 이를 안전하게 전달하기 위한 '대피소'로서 임시 객체가 생성됩니다.
🛠️ 성능 저하를 막는 필살기
- 참조자(&) 활용: 인자를 전달할 때 const T&를 사용하여 복사 생성자 호출을 원천 차단합니다.
- 이동 시맨틱(Move Semantics): 데이터를 복사하지 않고 소유권만 이전합니다. (TMoveTemp)
- RVO (Return Value Optimization): 컴파일러가 반환 값을 생성 위치에 바로 구축하도록 유도합니다.
'C++ 공부' 카테고리의 다른 글
| [C++ Study] friend, 상속의 경계, 그리고 static의 메모리 전략 (0) | 2026.04.10 |
|---|---|
| [C++ Study] Side Effect, Android Vulkan, 그리고 현대적 상수(const/constexpr/consteval) (0) | 2026.04.09 |
| 소수 판별하기 (0) | 2025.10.31 |
| N번째 큰 수 찾기 (std::nth_element) (0) | 2025.10.24 |
| 25.10.05 연습문제 풀이 (범위 기반 반복문) (0) | 2025.10.07 |