반응형

1. 스마트 포인터란?

  1. 스택의 포인터 변수가 없어질 때 자동 메모리 해제
  2. 종류
    • unique_ptr
    • shared_ptr
    • weak_ptr

2.unique_ptr

  1. exclusive ownership
    • 한 오브젝트에 하나의 포인터만 허용함
  2. 생성 방법
unique_ptr<Cat> catPtr = make_unique<Cat>()
  1. get 함수 또는 연산자를 통해 자원 접근 가능
//operator -> 를 이용해 자원 접근
catPtr->doSomething();

// get함수를 통해 자원 접근
catPtr.get() //포인터를 반환
  1. std::move를 통해 소유권 이전 가능
    • 소유권을 이전한 unique_ptr을 댕글링 포인터(dangling pointer) 라고 함
unique_ptr<Cat> catPtr1 = move(CatPtr)
  1. unique_ptr을 함수 인자로 전달하기
    • unique_ptr은 복사를 수행하지 않기 때문에 함수 인자로 전달 불가
    • unique_ptr에서 관리하는 자원을 직접 전달
void do_something(Cat* ptr) { };
do_something(catPtr.get());
  1. unique_ptr을 원소로 가지는 컨테이너에서 사용 방법
std::vector<std::unique_ptr<A>> vec;
std::unique_ptr<A> pa(new A(1));

//1. 복사 생성자가 없기 때문에 오류 발생!
vec.push_back(pa);

//2. 소유권을 이전하면서 vector에 추가
vec.push_back(std::move(pa));

//3. emplace_back 사용 시 생성하면서 컨테이너에 넣을 수 있음
vec.emplace_back(new A(1));
  1. 주로 멤버 변수가 포인터일 경우 사용

3. shared_ptr

  1. Shared ownership
    • 한 오브젝트에 여러 포인터 가능함
  2. Reference count를 계산하여, 아무도 가리키지 않을 때 자동으로 메모리 해제
  3. 생성 방법
shared_ptr<Cat> catPtr = make_shared<Cat>()
  1. 자원을 할당 시 주의 사항
    • 자원을 먼저 할당하고 shared_ptr 생성자 인자로 주소값을 전달하지 않도록 하자!
A* a = new A();
// 2개의 shared_ptr 객체가 각각 따로 제어블록을 생성함
// 참조계수가 각각 1을 가짐
std::shared_ptr<A> pa1(a);
std::shared_ptr<A> pa2(a);
  1. 클래스에서 this를 사용해 shared_ptr을 만들 때
    • 클래스에서 enable_shared_from_this<A> 를 상속 받음
    • shared _from _this()를 통해 this를 shared_ptr로 만들자!
class A : public std::enable_shared_from_this<A>{
   std::shared_ptr<A> get_shared_ptr() {
      return shared_from_this();
   }
}
  1. 원형 참조가 있으면 여전히 메모리 릭 발생 가능
    • weak_ptr을 통해 해결 가능
class Cat{
public:
   std::shared_ptr<Cat> mFriend;
};

int main(){
   std::shared_ptr<Cat> pKitty = std::make_shared<Cat>();
   std::shared_ptr<Cat> pNabi = std::make_shared<Cat>();

   pKitty->mFriend = pNabi;
   pNabi->mFriend = pKitty;
}

4. weak_ptr

  1. 일반 포인터와 shared_ptr 사이에 위치한 스마트 포인터
  2. 참조하여도 reference count가 증가되지 않음
  3. weak_ptr 자체로는 원래 객체를 참조할 수 없음
    • weak _ptr 생성시 shared _ptr 또는 weak _ptr을 생성자 인자로 받음
    • 일반 포인터 주소값으로 weak_ptr 생성 불가
    • 가리키는 객체가 이미 소멸되었으면, 빈 shared_ptr로 변환
    • 아닐 경우 해당 객체를 가리키는 shared_ptr로 변환
  4. lock 함수를 통해 shared_ptr로 변환
std::weak_ptr<A> other(std::shared_ptr<A>(new A(1)));
std::shared_ptr<A> o = other.lock();

참고

반응형

'C++ > C++' 카테고리의 다른 글

[C++] 함수형 프로그래밍  (0) 2021.03.11
[C++]병렬 프로그래밍  (0) 2021.03.11
[C++]LR value 및 최적화  (0) 2021.03.09
[C++]빌드 프로세스  (0) 2021.03.09
[C++]메모리 구조  (0) 2021.03.09

+ Recent posts