Effective C++/More Effective C++
[More Effective C++] 19. 임시 객체(temporaries)
김디트
2024. 8. 26. 10:56
728x90
항목 19 : 임시 객체의 원류를 정확히 이해하자.
임시 객체(temporaries)
- 아래의 경우를 임시 객체라 할 수 있을까?
templcate<typename T>
void swap(T& object1, T& object2)
{
T temp = object1; // 임시 객체? 아니고 그저 지역 객체
object1 = object2;
object2 = temp;
}
- 그렇다면 임시 객체란 무엇일까?
- C++에서의 진짜 임시 객체는 힙 이외의 공간에 생성되는 ‘이름 없는’ 객체이다.
- 즉, 코드 상에서는 드러나지 않는다.
- 이름 없는 객체가 만들어지는 상황
- 함수 호출의 매개변수로 암시적 타입 변환이 적용될 때
- 함수가 객체를 값으로 반환할 때
- 임시 객체의 생성, 소멸 비용은 전체 성능에 의외로 꽤 영향을 준다.
함수 호출의 매개변수로 암시적 타입 변환이 적용될 때
// str 안에 들어 있는 ch의 출현 횟수를 반환한다.
size_t countChar(const string& str, char ch);
char buffer[MAX_STRING_LEN];
char c;
// 문자열을 읽을 때 버퍼가 넘치는 것을 막기 위해 setw를 사용.
cin >> c >> setw(MAX_STRING_LEN) >> buffer;
// buffer은 char[]이지만, countChar은 매개변수로 const string&을 받는다.
// 즉, 암시적 변환이 발생한다.
// char 타입 배열을 string 타입 임시 객체로 만든다.
// 이 임시객체는 countChar가 복귀할 때 자동으로 소멸한다.
cout << "There are " << countChar(buffer, c)
<< " occurrences of the character " << c
<< " in " << buffer << endl;
- 효율의 관점에서 볼 때 임시 string 객체가 매번 생성되었다 소멸되는 것은 불필요한 낭비이다.
- 해결법
- 코드를 다시 설계하여 암시적 변환이 발생하지 않도록 한다. (항목 5 참조)
- 비상수 객체 참조자(reference-to-non-const) 타입 매개변수를 사용하면 암시적 변환이 발생하지 않는다.
- 객체가 값(value)이나 상수 객체 참조자(reference-to-const)로 전달될 때만 암시적 변환이 발생한다.
-
void uppercasify(string& str); char subtleBookPlug[] = "Effective C++"; uppercasify(subtleBookPlug); // 에러 발생!! // 왜냐하면, str은 내부에서 변경 가능한데(non-const) // 임시 객체를 변경하는 일은 무의미하기 때문이다.
- 비상수 객체 참조자(reference-to-non-const) 타입 매개변수를 사용하면 암시적 변환이 발생하지 않는다.
- 애초에 타입 변환이 불필요하도록 소프트웨어를 수정한다. (항목 21 참조)
- 코드를 다시 설계하여 암시적 변환이 발생하지 않도록 한다. (항목 5 참조)
함수가 객체를 값으로 반환할 때
const Number operator+(const Number& lhs, const Number& rhs);
- 이 함수의 반환값은 이름이 없으므로 임시 객체이다.
- 반환값이 const인 이유는.. (항목 6 참조)
- 이 함수를 호출할 때마다 임시객체가 만들어졌다가 없어지는 일을 반복한다.
728x90