일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- UE5
- cpp개발
- 디자인패턴
- 프로세스
- C++
- 데이터구조
- 복사생성자
- 언리얼엔진
- 포인터
- CPP
- 게임프로그래밍패턴
- Unreal
- Unreal Engine
- 자료구조
- 언리얼5
- 게임개발
- effectivec++
- 언리얼
- 언리얼 엔진5
- BehaviorTree
- 게임 개발
- AI
- 복사대입연산자
- Vector
- 언리얼엔진5
- 프로그래밍
- 배열
- Unreal Engine5
- C언어
- 스마트포인터
Archives
- Today
- Total
리얼 개발
[C++] RVO, NRVO 본문
#include <iostream>
#include <string>
using namespace std;
#define LOG(Str, Number) cout << Str << " Spawn Number : " << Number << endl;
class Test
{
public:
Test() { LOG("Test 일반 생성자", ++SpawnNumber); }
~Test() { LOG("Test 소멸자", --SpawnNumber); }
Test(const Test& arg) { LOG("Test 복사 생성자", ++SpawnNumber); }
Test& operator=(const Test& arg) { LOG("Test 복사 대입 연산자", SpawnNumber); return *this; }
private:
static int SpawnNumber;
};
int Test::SpawnNumber = 0;
Test NRVOFunc()
{
Test t;
return t;
}
Test RVOFunc()
{
return Test();
}
int main()
{
Test t = RVOFunc();
Test tt = NRVOFunc();
Test ttt = t;
return 0;
}
해당 프로그램의 출력 결과는 어떻게 나올지 고민해보자.
고민 다 하셨나요?
출력 결과는 다음과 같다.
고민한 부분과 비슷할 수도, 아닐 수도 있는데 그 이유는 컴파일러가 똑똑해서다.
NRVOFunc() 함수를 호출했을 때 동작 순서는 다음과 같을 것이다.
- NRVOFunc 함수 내에서 지역 변수 Test t 선언으로 일반 생성자 호출
- 리턴값을 위해 t 객체를 이용한 복사 생성
- t 객체의 소멸자 호출
- Test t = RVOFunc() 에서 RVOFunc() 의 자리는 복사 생성으로 리턴된 객체가 있음
- Test t 는 복사 생성으로 리턴된 객체를 복사 생성
- 리턴된 객체의 소멸자 호출
즉 일반 생성자 1번, 복사 생성자 2번, 소멸자 2번이 호출이 보통의 기댓값이다.
근데 어차피 함수 리턴값으로 객체를 생성할건데 이렇게 임시 객체를 만들고 복사할 필요가 있을까?
정답은 없다이다.
두 가지의 최적화 방법이 있는데, 첫 번째는 우측값을 활용하는 것이다.
Test NRVOFunc()
{
Test t;
return std::move(t); // 이동 생성자 호출
}
클래스에 이동 생성자가 정의되어 있는 경우 사용 가능하다.
하지만 이건 프로그래머가 직접 구현해줘야 하는 것이고, 원래는 컴파일러가 자동적으로 리턴값을 최적화 해준다. 이것을 Return Value Optimization(RVO) 이라 부른다.
정리하면 RVO란 리턴 값으로 임시 객체를 생성하여 반환하지 않는 기술을 말한다.
위에서 말한 NRVO는 Named Return Value Optimization으로 이름을 가진 객체가 반환 되었음에도 복사되지 않는 것을 의미한다.
'C++ > 어려운 C++' 카테고리의 다른 글
[C++] STL 직접 구현해보기 - vector, iterator (0) | 2025.05.08 |
---|---|
[C++] STL 직접 구현해보기 - 스마트 포인터 (0) | 2025.05.08 |
[C++] 초기화 (0) | 2025.04.15 |
[C++] 7. 클래스 (0) | 2024.07.30 |
[C++] 6. 포인터와 참조 (0) | 2024.06.28 |