15. string 클래스와 표준 템플릿 라이브러리(2) - 스마트 포인터

WanJu Kim·2022년 12월 19일
0

C++

목록 보기
66/81

동적 할당은 유용하다. 근데 좀 귀찮은 게 있다. 바로 delete이다. 귀찮지만 안 적으면 매우 위험하다. 그래서 우리가 해야 할 건 "주의하기". 하지만 가끔씩 까먹을 때가 있다. 그럴 때를 위해 '스마트 포인터'를 만들었다.

스마트 포인터는 3개(auto_ptr, unique_ptr, shared_ptr)가 있고, 모두 동적 할당한 객체가 수명이 다했을 때(코드 블럭이 끝나는 등), 메모리를 자동으로 파괴해준다. iostream 클래스 안에 있고 이런 식으로 사용한다.

std::auto_ptr<string> ps(new string);
// delete ps;	// 적을 필요 없다.

하지만 그로 인해 문제가 생기는 것도 있다. 다음 코드를 보자.

std::auto_ptr<string> ps("auto_ptr");
std::auto_ptr<string> vocation;
vacation = ps;

무엇이 문제인가? 스마트 포인터는 자동으로 파괴자를 호출하기 때문에, 이 경우에는 같은 주소를 두 번 파괴하기 때문에 문제가 생긴다. 이를 위해서 각각의 스마트 포인터는 해결책을 또 만들어놓았다.

auto_ptr은 하나의 객체를 다른 곳에 대입하는 순간 원래 객체는 힘을 잃어버린다.

shared_ptr은 '참조 카운터' 개념을 만들었다. 객체를 공유할 때마다 참조 카운터가 +1씩 올라가고, 수명이 다 할 때마다 -1씩 줄어든다. 결국 마지막 스마트 포인터 수명이 다 하면 delete를 호출한다.

unique_ptr은 애초에 객체 공유를 하지 못하게 한다. 아까 코드에서 auto_ptr를 unique_ptr로 바꾸면 에러가 난다. 하지만 이건 표준 라이브러리 함수 std::move 함수를 쓰면 가능하다.그러면 auto_ptr와 같은 역할을 한다. unique_ptr은 유니크해서 하나밖에 못 만드니, 아예 객체를 옮기겠다는 거다.

std::unique_ptr은<string> ps("auto_ptr");
std::unique_ptr은<string> vocation;
vacation = ps;	// 여기서 에러가 난다.
vacation = std::move(ps)	// ps 객체는 힘을 잃어버림.

또한 unique_ptr와 shared_ptr은 auto_ptr와 다르게 array로 사용할 수 있다.

std::auto_ptr<string[]> p1(new string("hi"));	// 불가능.
std::shared_ptr<string[]> p2(new string("hi"));
std::unique_ptr<string[]> p3(new string("hi"));
profile
Question, Think, Select

0개의 댓글