스마트 포인터 / weak_ptr 위크 포인터
태그: C++, Cpp, pointer, smart pointer, weak_ptr
카테고리: Cpp
🤯 언리얼을 하기 위해 C++ 기억 되살리기 프로젝트
std::weak_ptr
약한(weak) 참조
- 약한 참조는 원시 포인터 해제에 영향을 끼치지 않음
- 약한 참조 카운트는 약한 참조의 수를 저장하는 데에 사용됨
- 약한 참조로 참조되는 개체는
강한 참조 카운트가 0이 될 때 소멸됨
- 순환 참조 문제의 해결책
예시: 약한 포인터 만들기
아무 것도 없는데 약한 포인터 만들 순 없음.
1
2
3
4
5
6
7
8
9
int main()
{
std::shared_ptr<Person> owner = std::make_shared<Person>("Pope"); // 강한 참조
std::weak_ptr<Person> weakOwner = owner; // 약한 참조는 강한 참조로부터 나올 수 밖에 없음.
// shared_ptr 로부터 weak_ptr를 만드는 것
return 0;
}
예시: 약한 포인터로 공유 포인터 만들기 : Lock()
1
2
3
4
5
6
7
8
int main()
{
std::shared_ptr<Person> owner = std::make_shared<Person>("Pope");
std::weak_ptr<Person> weakOwner = owner;
std::shared_ptr<Person> lockedOwner = weakOwner.Lock(); // <--- 이거!
}
약한 포인터를 쓰고 싶을 땐 공유 포인터로 바꿔서 써야 함.
약한 포인터에 Lock()
을 하면 공유 포인터를 뱉어줌.
이 때 강한 참조 카운트가 하나씩 올라가게 됨.
원시 포인터가 존재하면 공유 포인터를 만든다.
예시2: 공유 포인터가 존재하는지 확인 : expired()
1
2
3
4
5
6
7
8
9
10
11
int main()
{
std::shared_ptr<Person> owner = std::make_shared<Person>("Pope");
std::weak_ptr<Person> weakOwner = owner;
if (weakOwner.expired()) // true : 만료되었다는 뜻... 죽었다는 뜻
{ // false : 살아있다는 뜻. 포인터 써도 됨
// ...
}
}
하지만 멀티 쓰레딩 환경에선, 포인터가 살아있음을 확인하고 쓰려고 하는 순간에
다른데서 지워버리는 상황이 발생할 수 있음.
그러니까expired()
는 죽었는지 확인하는 용도로만 쓰고,
보통은Lock()
을 걸어주자~
댓글남기기