티스토리 뷰

선호 이유

간결한 코드

 설명을 하기 전에 코드를 먼저 살펴보자.

auto spw1(std::make_shared<Widget>());

std::shared_ptr<Widget> spw2(new Widget());

 먼저 코드의 길이부터 약간이지만 더 짧아진 것을 확인할 수 있다. 또한 타입 선언을 한 번만 작성하는 곳을 볼 수 있는데, 이는 소프트웨어 공학의 핵심 교의 중 하나인 "코드 중복을 피하라"를 잘 지키는 것이다. 소스 코드의 중복이 많으면 컴파일 시간이 늘어나며 일관성이 없는 코드로 진화하기 일쑤이다. 코드의 비일관성은 버그로 이어지는 경우가 많다. 

예외 안정성

 이 역시 코드를 먼저 살펴보자.

void processWidget(std::shared_ptr<Widget> spw, int priority);

int computePriority();

processWidget(std::shared_ptr<Widget>(new Widget),
              computePriority());

 위 코드는 마치 문제가 없는 것처럼 보이지만 누수가 발생할 수 있다. 함수를 호출하는 코드를 세분화하면 3단계로 나뉜다.

  • new Widget
  • std::shared_ptr<Widget>()
  • computePriority()

Widget 을 생성자와 shared_ptr 의 생성자는 순서대로 진행되지만 그 중간에 computePriority() 함수가 호출될 수 있다. 그런데 만약 computePriority() 함수에서 예외가 발생하면 Widget 객체는 누수가 발생하게 된다.

 make_shared 함수를 사용했더라면 예외가 발생했더라도 Widget 객체는 shared_ptr 로 관리되어 누수가 발생하지 않았을 것이다.

메모리 할당의 효율성

 이전 포스팅에서 설명했듯이 shared_ptr 에는 control block 이 생성된다.

https://pppgod.tistory.com/40

불러오는 중입니다...

 객체를 생성하는데 한 번, control block 을 생성하는데 한 번, 총 두 번의 메모리 할당이 발생한다. 하지만 make_shared 는 한 번에 두 개 모두 할당해버리기 때문에 보다 효율적이다. 한가지 문제가 있다면 newdelete 연산자를 오버로딩하게 되면 원치않는 결과로 이어질 수 있다는 점을 유의하자.

사용하지 못하는 상황

커스텀 삭제자

 make 함수를 이용하게 되면 커스텀 삭제자를 사용할 수 없다. 

std::initializer_list

 vector 를 예를 들어보자. 

auto spv = std::make_shared<std::vector<int>>(10, 20);

 위의 함수는 10, 20 을 원소로 갖는 벡터가 생성될까? 아니면 값이 20인 10개 짜리 원소를 갖는 벡터가 생성될까? 

 정답은 값이 20인 10개짜리 원소이다. 만약에 10과 20을 원소를 갖는 벡터를 생성하고 싶으면 어떻게 해야할까? 정답은 간단하다.

auto initList = { 10, 20 };

auto spv = std::make_shared<std::vector<int>>(initList);

control block

 앞에서 말했듯이 make 함수는 메모리를 한 번에 할당한다. 해제도 마찬가지로 한 번에 해제해야한다. 문제는 control block 에는 weak 참조 횟수도 저장하기 때문에 weak_ptr 가 존재하는 한, 해제할 수 없다. 만약 newshared_ptr 를 생성했다면 control block 도 따로 생성되기 때문에 weak_ptr 가 존재하여도 소멸될 수 있다. 만약 메모리 크기가 매우 큰 객체를 생성한다면 make 를 사용하지 않는 것이 메모리 관리에 유리할 것이다.

 

참고 서적

스콧 마이어스, Effective Modern C++

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함