Publish:

태그: , , , ,

카테고리:


🤯 언리얼을 하기 위해 C++ 기억 되살리기 프로젝트

std::shared_ptr

예시: std::shared_ptr 만들기

1
2
3
4
5
6
7
8
9
10
#include <memory>
#include "Vector.h"

int main()
{
    std::shared_ptr<Vector> vector = std::make_shared<Vector>(10.f, 30.f);

    // vector 는 셰어드 포인터가 되고,
    // 참조 카운트는 1이 되었을 것이다 - 라고 추측 가능!
}

make_shared 는 C++14 부터 지원되는 거고, 쓸 수 없다면
std::shared_ptr<Vector> vector(new Vector(10.f, 30.f));

  • 두 개의 포인터를 소유
    • 데이터(원시 포인터)를 가리키는 포인터
    • 제어 블록을 가리키는 포인터
      • 참조 카운트 세야 하니까~ 참조 카운트 가지고 있을 메모리 공간 필요하니까 만들어 두는 것
    • 데이터 ptr -> 데이터
      제어 블록 ptr -> 강한 참조 횟수, 약한 참조 횟수
  • std::unique_ptr와 달리, 포인터를 다른 셰어드 포인터와 공유 가능
  • 참조 카운팅 기반
  • 원시 포인터는 어떠한 std::shared_ptr 에게도 참조되지 않을 때 소멸됨

예시: 포인터 공유하기

1
2
3
4
5
int main()
{
  std::shared_ptr<Vector> vector = std::make_shared<Vector>(10.f, 30.f);
  std::shared_ptr<Vector> copiedVector = vector;
}

똑같은 것을 가리키게 되고,
레퍼런스 카운트도 똑같아짐.

예시: 포인터 재설정하기

1
2
3
4
5
6
int main()
{
  std::shared_ptr<Vector> vector = std::make_shared<Vector>(10.f, 30.f);
  std::shared_ptr<Vector> copiedVector = vector;
  vector.reset();                                     // vector = nullptr 과 같음~!
}

두번째 줄 까진 둘 다 참조 카운트가 2가 됨. (가리키는 셰어드 포인터가 vector, copiedVector 2개니까)

코드 끝까지 다다르면 최종적으로 vector는 empty가 되고,
copiedVector 의 참조 카운트는 1이 됨.

  • 원시 포인터를 해제한다
    • 포인터 들고 있는걸 더이상 참조하지 않겠다, nullptr 로 바꾸겠다는 거고,
      참조 카운트 1이 줄어듦.
    • 그렇다고 원시 포인터의 소멸자를 호출하진 않음. (지우진 않는다는 의미)
    • 참조 카운트가 0이 되기 전에는 원시 포인터의 소멸자를 호출하진 않음!!!
  • nullptr 를 대입하는 것과 같음

예시: 참조 횟수 구하기

1
2
3
4
5
6
7
8
9
10
11
int main()
{
  std::shared_ptr<Vector> vector = std::make_shared<Vector>(10.f, 30.f);
  std::cout << "vector : " << vector.use_count() << std::endl;            // vector : 1

  std::shared_ptr<Vector> copiedVector = vector;
  std::cout << "vector : " << vector.use_count() << std::endl;            // vector : 2
  std::cout << "vector : " << copiedVector.use_count() << std::endl;      // copiedVector : 2 (똑같은 포인터 가리키고 있으니까)

  return 0;
}

이슈 및 공부한 것을 기록해두는 개인 블로그 입니다. 댓글, 피드백 환영합니다 🙂

Update:

댓글남기기