C++ 스마트 포인터 weak_ptr
금일 정리해볼 내용은 스마트 포인터 중 weak_ptr 관련된 내용이다. shared_ptr 은 자신이 참조하고 있는 메모리에 대해 참조 카운터를 증감시킴으로써 객체의 수명을 관리하도록 되어 있었다.
하지만 weak_ptr 은 shared_ptr 의 참조 카운팅에 포함되지 않는다. shared_ptr 의 소유 포인터를 참조만할 뿐 참조 카운터에는 영향을 주지 않는 것이다. 내부적으로 shared_ptr 을 더 보게 되면 참조 카운터를 관리하는 변수가 두 개로 나뉘어져 있으며 strong reference count 와 weak reference count 이다. shared_ptr 끼리의 참조는 strong reference count 가 증가되며 weak_ptr 에 의한 참조는 weak reference count를 증가시킨다. 하지만 weak refernce count 는 shared_ptr 의 소유 포인터에 대한 메모리 해제에 영향을 주지 않는다.
다음 코드를 확인해보자.
#include <iostream>
#include <memory>
using namespace std;
int main()
{
shared_ptr<int> sp1( new int(1));
weak_ptr<int> wp1 = sp1;
{
shared_ptr<int> sp2 = wp1.lock();
if(sp2){
//do something.
}
}
sp1.reset();
shared_ptr<int> sp3 = wp1.lock();
if(sp3){
//스코프로 진입되지 않는다.
}
return 0;
}
위 코드를 보면 알 수 있는 것은 weak_ptr 은 해당 포인터에 접근하기 위해서는 lock() 함수를 사용하여 shared_ptr 로 변환하여 접근하는 방법이 유일하다.
weak_ptr 은 보통 순환 참조 문제를 해결하기 위해서 많이 사용된다. 다음 코드를 보도록 하자.
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
class Circular;
class Problem
{
public:
Problem(){}
~Problem(){
m_List.clear();
}
public:
void addUnit(const shared_ptr<Circular>& c){
m_List.push_back(c);
}
void DoSomething(){
}
private:
vector<shared_ptr<Circular>> m_List;
};
class Circular
{
public:
void SetProblem(const shared_ptr<Problem>& p){
m_Problem = p;
}
void DoSomething(){
if(m_Problem.expired() == false){
shared_ptr<Problem> sp = m_Problem.lock();
if(sp){
sp->DoSomething();
}
}
}
private:
weak_ptr<Problem> m_Problem;
//shared_ptr<Problem> m_Problem;
};
int main()
{
shared_ptr<Problem> pb(new Problem);
for(int i=0; i<10;i++){
shared_ptr<Circular> sp(new Circular);
pb->addUnit(sp);
sp->SetProblem(pb);
}
pb.reset();
return 0;
}
위 코드에서 weak_ptr<Problem> 대신 shared_ptr<Problem> 이 이용된다면 main 함수의 pb.reset() 시 Problem 을 소멸시키고자 하지만 Problem 안에 Circualr 들이 모두 하나씩 가지고 있기 때문에 메모리가 해제되지 않는 문제가 발생한다. 이러한 문제들을 해결하고자 weak_ptr 을 쓰면 좋은 예가 될 수 있다.
이전 포스팅
2022.01.16 - [프로그래밍/C/C++] - [C++] 스마트포인터 unique_ptr [정보공유의 장]
'프로그래밍 > C/C++' 카테고리의 다른 글
[C++] 스마트포인터 unique_ptr [정보공유의 장] (0) | 2022.01.16 |
---|---|
[C++] explicit - 정보공유의 장 (0) | 2022.01.15 |
[C++] 스마트포인터 shared_ptr - 정보공유의 장 (0) | 2022.01.15 |
C++ template with member function (0) | 2022.01.13 |
C++ Template and Integral_constant (0) | 2022.01.12 |