주간 팁 #123: absl::optionalstd::unique_ptr

원래 게시일: 2016-09-06
작성자: Alexey Sokolov (sokolov@google.com)
Etienne Dechamps (edechamps@google.com)


값을 저장하는 방법

이 팁에서는 값을 저장하는 여러 가지 방법을 다룹니다. 여기서는 클래스 멤버 변수를 예로 들지만, 아래의 많은 점은 지역 변수에도 적용됩니다.

CPP
#include <memory>
#include "absl/types/optional.h"
#include ".../bar.h"

class Foo {
  ...
 private:
  Bar val_;
  absl::optional<Bar> opt_;
  std::unique_ptr<Bar> ptr_;
};
클릭하여 더 보기

1. 일반 객체로 저장

val_은 가장 단순한 방식입니다.

장점:

단점:

  1. val_의 수명은 Foo 객체의 수명에 고정됩니다.
    • 교체 가능성: Bar가 이동(이사) 또는 교체 연산을 지원한다면, 기존의 참조는 여전히 유효하지만 내용은 변경할 수 있습니다.
  2. Bar 생성자에 전달할 인수는 반드시 Foo 생성자의 초기화 리스트에서 계산되어야 합니다. 복잡한 표현식이 필요한 경우 어렵습니다.

2. absl::optional<Bar>로 저장

absl::optional은 일반 객체와 std::unique_ptr의 중간 수준의 유연성을 제공합니다.

주의사항:

  1. 비어 있는 absl::optional도 메모리를 사용합니다. (할당된 것과 동일한 크기)
  2. 객체가 언제 생성되고 소멸되는지 명확하지 않을 수 있습니다.
  3. 비어 있는 상태에서 접근하면 문제가 발생할 수 있습니다.

3. std::unique_ptr<Bar>로 저장

가장 유연한 방법입니다.

장점:

  1. 소유권 이전 및 이동 가능.
  2. 객체가 동적으로 생성되므로, 더 많은 제어가 가능.

단점:

  1. 복잡성 증가:
    • 독자가 내부 구조를 이해하는 데 시간이 걸릴 수 있습니다.
    • 객체 생성 및 소멸 시점이 덜 명확합니다.
  2. CPU 캐시 비효율성:
    • 추가 간접 참조로 인해 힙 할당이 발생하고 CPU 캐시 친화도가 낮아집니다.
  3. 복사 불가:
    • std::unique_ptr<Bar>는 복사할 수 없으므로 Foo도 복사할 수 없습니다.

결론


비교표

Barabsl::optional<Bar>std::unique_ptr<Bar>
지연 초기화 지원
항상 안전한 접근
소유권 이전 지원
Bar의 하위 클래스 저장
이동 가능Bar가 이동 가능할 경우Bar가 이동 가능할 경우
복사 가능Bar가 복사 가능할 경우Bar가 복사 가능할 경우
CPU 캐시 친화적
힙 할당 없음
메모리 사용량sizeof(Bar)sizeof(Bar) + sizeof(bool)sizeof(Bar*) (null일 때)
객체 수명포함하는 스코프와 동일포함하는 스코프 내 제한제한 없음
f(Bar*) 호출f(&val_)f(&opt_.value()) 또는 f(&*opt_)f(ptr_.get()) 또는 f(&*ptr_)
값 제거 방법N/Aopt_.reset(); 또는 opt_ = absl::nullopt;ptr_.reset(); 또는 ptr_ = nullptr;

라이선스

저작자: Jaehun Ryu

링크: https://jaehun.me/posts/abseil-tip-123-absloptional%EA%B3%BC-stdunique_ptr/

라이선스: CC BY 4.0

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

댓글

검색 시작

검색어를 입력하세요

↑↓
ESC
⌘K 단축키