아래는 “이번 주의 팁 #107: 참조 수명 확장"에 대한 한글 번역입니다:


제목: “이번 주의 팁 #107: 참조 수명 확장”
원문 게시일: 2015년 12월 10일
작성자: Titus Winters (titus@google.com)


개요

TotW #101 이후로 참조와 수명에 대한 혼란이 보고되었습니다. 이 팁에서는 다음 질문에 대해 자세히 알아보겠습니다:
“참조 수명 확장은 언제 적용되나요?”

CPP
string Foo::GetName();

const string& name = obj.GetName();  // 이 코드는 안전할까요? 합법적일까요?
클릭하여 더 보기

간단히 말해, 임시 객체(참조 대상)의 수명은 다음 조건에서만 연장됩니다:

  1. 지역 변수 const T& 또는 T&&이 **임시 T**를 반환하는 표현식의 결과로 초기화되거나,
  2. 임시 객체의 T 하위 객체(예: 구조체의 멤버 변수)를 참조할 때.

(Google 스타일에서는 주로 T&&는 무시합니다.)

표준 문서는 다소 복잡할 수 있으므로, 몇 가지 경계 사례를 통해 이를 명확히 설명하겠습니다.


수명 확장의 적용 사례와 예외

  1. T&에는 적용되지 않습니다. 반드시 const T&이어야 합니다.

    • T&로 초기화하려 하면 컴파일 오류가 발생합니다.
  2. 형 변환이 있는 경우에는 수명 확장이 작동하지 않습니다.

    • 예를 들어, stringconst absl::string_view&로 할당하면 string의 수명이 연장되지 않습니다.
    • 참고로 const absl::string_view&는 사용하지 않는 것이 좋습니다.
  3. 간접적으로 하위 객체를 얻는 경우 수명 확장이 작동하지 않습니다.

    • 컴파일러는 함수 호출(예: getter)을 통해 간접적으로 반환된 객체를 추적하지 않습니다.
    • 수명 확장은 표현식에서 반환된 임시 객체의 직접적인 멤버 변수에만 작동합니다.
  4. 형 변환이 허용되는 경우는 부모 클래스와 자식 클래스 간의 관계가 있는 경우뿐입니다.

    • 예를 들어, 부모 클래스 T와 자식 클래스 U가 있을 때, 자식 클래스 U의 임시 객체를 부모 클래스 T&로 참조할 수 있습니다. 하지만 이런 경우는 혼란을 초래할 수 있으므로 권장하지 않습니다.

수명 확장의 작동 방식


권장 사항

TotW #101에서 설명했듯이, 참조 초기화에서 수명 확장에 의존하는 것은 바람직하지 않습니다. 이는 유지보수성과 리뷰 과정에서 문제가 될 수 있습니다.

하지만, 수명 확장이 필요한 경우가 있습니다:

다음은 올바르게 작동하는 예입니다:

CPP
std::vector<int> GetInts();
for (int i : GetInts()) { }  // 벡터의 수명 확장이 중요합니다.

// 문자열을 각 문자(char) 단위로 분리하여 string_view로 반환합니다.
std::vector<absl::string_view> Explode(const string& s);

// 벡터의 수명은 연장되지만, 임시 문자열의 수명은 연장되지 않습니다.
for (absl::string_view s : Explode(StrCat("oo", "ps"))) { }  // 잘못된 코드
클릭하여 더 보기

다음은 수명 확장이 작동하지 않는 예입니다:

CPP
MyProto GetProto();

// MyProto가 스코프를 벗어나면서 sub_protos도 파괴됩니다. 
// 컴파일러는 sub_protos()가 하위 객체를 반환하는 것을 추적하지 못합니다.
for (const SubProto& p : GetProto().sub_protos()) { }  // 잘못된 코드
클릭하여 더 보기

결론

가능하면 수명 확장에 의존하지 말고, 코드를 명시적으로 작성해 유지보수성과 가독성을 향상시키세요.

라이선스

저작자: Jaehun Ryu

링크: https://jaehun.me/posts/abseil-tip-107-%EC%B0%B8%EC%A1%B0-%EC%88%98%EB%AA%85-%EC%97%B0%EC%9E%A5/

라이선스: CC BY 4.0

이 저작물은 크리에이티브 커먼즈 저작자표시 4.0 국제 라이선스에 따라 이용할 수 있습니다. 출처를 밝히면 상업적 목적을 포함해 자유롭게 이용 가능합니다.

댓글

검색 시작

검색어를 입력하세요

↑↓
ESC
⌘K 단축키