Publish:

태그: , , , ,

카테고리:


🤯 언리얼을 하기 위해 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() 을 걸어주자~


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

Update:

댓글남기기