[R value] 임시 객체 (temporary object) - ChoiChiWon/ccw GitHub Wiki
임시 객체 (temporary object)
- 이름이 없으며 stack memory에 잡히는 object
- 일반 object와는 달리 해당 라인의 세미 콜론을 만나면 파괴되는 속성을 가진다.
임시객체 pointer
- 해당 라인의 연산이 끝나고 파괴되는 속성이 있기 때문에 object의 주소값을 포인터 변수에 저장하는 것이 불가능하다.
foo p; // 일반 object
foo *p1 = &p; // ok
foo *p2 = &foo(); // error
임시 객체 와 rvalue
- 임시 객체는 rvalue에 해당된다.
- lvalue는 value가 사용되는 expression을 넘어서도 생존하는 값인데 반해 rvalue는 이름이 없고 해당 value가 사용되는 expression을 넘어서면 생존하지 않는 값이다.
foo p;
p.x = 1; // ok
foo().x = 10; // error
임시 객체와 reference
- 임시 객체는 해당 라인이 끝나면 파괴되기 때문에 일반 object처럼 reference를 가지는게 불가능하다.
- 언제 파괴될지 모르는 object의 주소를 참조하는다는 것은 위험한 코드이다.
- 하지만 const reference는 허용된다.
- 임시 객체의 reference 정보를 const 참조 변수에 넘기면 임시 객체의 lifetime은 연장된다.
- 하지만 const reference이기 때문에 값의 변경은 불가능하다.
- rvalue reference에 대해서도 성립된다.
foo p; // 일반 object
foo& ref = p; // ok
foo& ref2 = foo(); // error
const foo& ref3 = foo(); // ok
foo&& ref4 = foo(); // ok
임시객체 parameter Passing
- function call시에 parameter passing을 효율적으로 수행할 수 있다.
// 함수 foo의 parameter로 일반 object를 넘기는 예제
void foo(TmpClass p)
{
cout << "call foo" << endl;
}
void main()
{
TmpClass p;
foo(p); // 일반 object를 parameter로 넘긴다.
cout << "main end" << endl;
}
// 실행 결과
TmpClass 생성자 호출
TmpClass의 복사 생성자 호출
call foo
TmpClass 소멸자 호출
main end
TmpClass 소멸자 호출
- parameter를 const 참조로 넘길 경우 임시 객체를 생성하지 않으므로 복사 생성자와 소멸자 호출이 없다.
void foo(const TmpClass& p)
{
cout << "const reference call" << endl;
}
void main()
{
foo(TmpClass()); // 임시 객체로 넘긴다.
cout << "main end" << endl;
}
// 실행 결과
TmpClass 생성자 호출
const reference call
TmpClass 소멸자 호출
임시객체 return value : RVO
TmpClass foo()
{
TmpClass p();
return p; // 임시 객체가 생성되어 return
}
void main()
{
TmpClass p1();
p1 = foo();
cout << "end" << endl;
}
// 실행 결과
TmpClass 생성자 호출
TmpClass 생성자 호출
TmpClass 복사 생성자 호출
TmpClass 소멸자 호출
TmpClass 소멸자 호출
end
TmpClass 소멸자 호출
- 함수 foo의 return 값 반환 과정에서 임시 객체가 생성되면서 복사 생성자가 호출되고, 값을 반환한 뒤 파괴된다.
TmpClass foo()
{
return TmpClass(); // RVO
}
void main()
{
TmpClass p1();
p1 = foo();
cout << "end" << endl;
}
// 실행 결과
TmpClass 생성자 호출
TmpClass 생성자 호출
TmpClass 소멸자 호출
end
TmpClass 소멸자 호출
- 임시 객체를 생성과 동시에 return하여 return용 객체의 복사생성자와 소멸자 호출이 일어나지 않는다.
- 이런 return 기법을 Return Value Optimization(RVO)라고 한다.
참고 사이트
Lvalues and Rvalues (C++)
C++ Object Lifetimes
Temporary object lifetime - cppreference