스마트 포인터 / shared_ptr 셰어드 포인터
태그: C++, Cpp, pointer, shared_ptr, smart pointer
카테고리: Cpp
🤯 언리얼을 하기 위해 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 로 바꾸겠다는 거고,
- 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;
}
댓글남기기