◎ 임시 객체란 무엇인가?
우리가 흔히 말하는 임시 객체란 무엇일까? 흔히들 지역객체 == 임시객체라고 생각을 한다. 하지만 이건 잘못된 지식이다. (C++에 한정해서) 지역객체는 함수의 스택에 만들어지는 객체이다. C++에서의 임시 객체는 우리눈에 보이지 않는다. 소스 코드에도 보이지 않는다. 진짜 임시 객체라 함은 힙 이외의 공간에 생성되는 이름없는 객체를 말한다.
임시 객체를 생성하는 경우는 다음 두가지 경우가 있다.
1. 함수 호출을 성사 시키기 위해 암시적 타입변환이 적용될때.
위와 같은 경우에서 SomeFunction의 인자로 CHAR* 로 넘겼다. CHAR* 는 string 객체가 아니지만 우리의 자랑스런 컴파일러는 string 객체가 생성자로 CHAR* 를 받을 수 있다는걸 발견했다. 이 경우 컴파일러는 aStr을 생성자 인자로 하는 이름없는 string 객체를 만든다. 이 경우가 함수 호출을 성사 시키기 위해 암시적 타입변환이 이루어지면서 임시객체가 사용되는 경우이다.
2. 함수가 객체를 값으로 반환할때.(return by value)
위와 같은 코드에서 operator+ 가 const CTemp 의 이름없는 객체를 반환한다.
이러한 임시객체들은 우리가 모르는사이에 생성 및 소멸이된다. 해당 객체의 생성 및 소멸에 걸리는 시간이 아무리 미비한다고 한들 호출 횟수가 잦아짐에 따른 오버헤드는 어쩔수없는것이다. 그럼 이 임시객체들을 어떻게 해야 좋을까?
◎ 암시적 변환이 일어나지 않게 하자
1번과 같은 상황에서 임시 객체를 암시적으로 만든다고 했다. 그렇다면 우리가 이 암시적 타입변환을 막을 수 있지 않을까?
함수 호출시 암시적으로 임시 객체를 만드는 경우는 오직 객체가 값으로 인한전달일 경우와 상수 객체 참조자 타입의 매개변수로 객체가 전달될때이다.
그렇다면 함수 호출시 암시적 타입변환이 일어나지 않기 위해서는
1. 값에 의한 전달을 하지 않는다.(포인터로 넘기기, 참조자로 넘기기(상수참조자는 안된다))
2. 함수 호출시 인자를 비 상수 객체 참조자(const 가 붙어있지 않는 참조자 형식)로 넘길것
◎ 반환값 최적화(Return Value Optimization)
2번과 같은 함수가 값으로 값을 반환을 막기 위해서는 컴파일러를 믿을 수 밖에 없다. 현재 대부분의 컴파일러가 지원하는 반환값 최적화 방법을 사용하는 것이다.
위 클래스에서 눈여겨 볼 곳은 operator + 와 operator – 이다.
operator +, 혹은 – 는 어쩔 수 없이 값에 의한 전달을 해야되는 함수이다.
1. operator – 와 + 는 별 다른게 없이 하나는 지역객체를 생성 후 해당 객체를 리턴하고, 하나는 리턴값을 클래스의 생성자를 호출한 임시객체로 했다.
2. operator + 는 객체의 생성자를 호출한 것을 반환한다.
※ 리턴값 최적화란 operator + 내부처럼 반환하는 객체가 객체의 생성자를 호출하는 객체이면 임시 객체와 반환하는 임시 객체 모두를 없애고, 계산 결과값을 바로 호출한곳에 대입을 시켜준다.(요즘 컴파일러는 대부분지원한단다.)
어쩔수 없이 값에 의한 전달이 필요할 경우에는 위와 값이 리턴하는 객체는 생성자를 호출한 객체를 하면 리턴값 최적화의 효과를 얻을 수 있다.