https://younggwan.tistory.com/36
윗 글에서 std::shared_ptr 의 정의와 문제점에대한 정리를 했는데.
std::shared_ptr의 문제점이 였던 순환 참조 문제를 해결할 수 있는 std::weak_ptr을 정리해 봅시다.
정의
weak_ptr은 하나 이상의 shared_ptr 인스턴스가 소유하는 객체에 대한 접근을 제공하지만, 소유자의 수에는 포함되지 않는 스마트 포인터입니다.
shared_ptr은 참조 횟수(reference count)를 기반으로 동작하는 스마트 포인터입니다.
만약 서로가 상대방을 가리키는 shared_ptr를 가지고 있다면, 참조 횟수는 절대 0이 되지 않으므로 메모리는 영원히 해제되지 않습니다.
이렇게 서로가 상대방을 참조하고 있는 상황을 순환 참조(circular reference)라고 합니다.
weak_ptr은 바로 이러한 shared_ptr 인스턴스 사이의 순환 참조를 제거하기 위해서 사용됩니다.
멤버 함수
reset : 관리 객체의 소유권을 공개 합니다.
swap : 관리 객체를 교환합니다.
use_count : shared_ptr개체를 관리하는 개체 수를 반환합니다.
expired : 참조된 객체가 삭제되었는지 확인합니다.
lock : shared_ptr로 변환 해서 참조할 수 있게 합니다.(변환이 맞는지는 모르겠습니다)
owner_before : 약한 포인터의 소유자 기반 순서를 제공합니다.
사용 예제
#include <iostream>
#include <memory>
class TestClass
{
public:
std::string name;
std::weak_ptr<TestClass> m_Other_Class;
void TestFunc()
{
std::cout << "hahaha" << std::endl;
}
void Set_Class(std::weak_ptr<TestClass> _Value)
{
m_Other_Class = _Value;
}
void Access_Other_Class()
{
std::shared_ptr<TestClass> convert_weak_ptr = m_Other_Class.lock();
if (convert_weak_ptr)
{
std::cout << this->name.c_str() << " 접근 성공 -> " << convert_weak_ptr->name.c_str() <<std::endl;
}
else
{
std::cout << "접근 실패" << std::endl;
}
}
TestClass(std::string _name) : name(_name)
{
std::cout << this->name.c_str() <<" 생성자 호출" << std::endl;
}
~TestClass()
{
std::cout << this->name.c_str() << " 소멸자 호출" << std::endl;
}
};
int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
std::shared_ptr<TestClass> T_A = std::make_shared<TestClass>("A클래스");
std::shared_ptr<TestClass> T_B = std::make_shared<TestClass>("B클래스");
T_A->Set_Class(T_B);
T_B->Set_Class(T_A);
T_A->Access_Other_Class();
T_B->Access_Other_Class();
T_B.reset();
T_A->Access_Other_Class();
}
결과
A클래스 생성자 호출
B클래스 생성자 호출
A클래스 접근 성공 -> B클래스
B클래스 접근 성공 -> A클래스
B클래스 소멸자 호출
접근 실패
A클래스 소멸자 호출
순환 참조의 소멸자 호출이 없어서 릭이 남던 문제가 없어지고 정상적으로 작동을 한다.
'게임 프로그래밍 > C++ 기초' 카테고리의 다른 글
C++ #define 매크로 상수, 매크로 함수 (0) | 2020.03.08 |
---|---|
C++ 얕은복사(Shallow Copy) 깊은복사(Deep Copy) (2) | 2020.03.04 |
std::shared_ptr 정의 및 문제점 (0) | 2020.03.02 |
C++ new, malloc (0) | 2020.03.02 |
오버로딩 (Overloading) (0) | 2020.03.02 |