본문 바로가기

C,C++

스마트 포인터(C++)

http://tcpschool.com/cpp/cpp_template_smartPointer

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com

class AAA
{
public:
	string m_str;

public:
	AAA()
	{
		printf("생성자 호출\n");
	}

	AAA(const string str)
	{
		m_str = str;
		cout << m_str << " 생성자 호출\n";
	}

	~AAA()
	{
		cout << m_str << " 소멸자 호출" << '\n';
	}
};

int main()
{
	// unique_ptr은 하나의 스마트 포인터만이 특정 객체를 소유할 수 있도록,
    // 객체에 소유권 개념을 도입한 스마트 포인터이다.
    
    // 해당 객체의 소유권을 가지고 있을 때만 소멸자가 해당 객체를 삭제할 수 있다.
	unique_ptr<AAA> pA = make_unique<AAA>("Unique");
	unique_ptr<AAA> pB;
    
	// pA에서 pB로 소유권 이전, pA는 empty상태가 된다.
    // move를 통해 소유권 이전은 가능하나, 복사는 불가능하다.
	pB = move(pA);
	
    // shared_ptr은 하나의 특정 객체를 참조하는 스마트 포인터가 총 몇 개인지를 참조하는
    // 스마트 포인터이다.
    
    // pS가 특정 객체를 참조하고 있으므로 ref count가 1이 되고, pT가 pS가 가리키는 객체를
    // 참조하고 있으므로 count가 2가 된다. 이 ref count가 0이 될 때 delete된다.
	shared_ptr<AAA> pS = make_shared<AAA>("Shared");
	shared_ptr<AAA> pT = pS;
	shared_ptr<AAA> pTmp = make_shared<AAA>("Shared2");

	printf("%d %d\n", pS.use_count(), pT.use_count());
	
    // .reset()을 통해서 스마트 포인터가 참조하는 것을 끊을 수 있다.
    // 끊게 되면 참조하고 있던 객체의 ref count가 감소하고, ref count가 0이 되면
    // 소멸자가 호출된다.
	pT.reset();
	printf("%d\n", pS.use_count());
	pTmp = pS;
	printf("%d\n", pS.use_count());
    
    // 만약 서로를 가리키는 shared_ptr이 존재한다면, 이 둘의 참조 횟수가 0이 되지 않으므로
    // 소멸자가 호출되지 않는다.
    // 이러한 순환 참조(circular reference)를 제거하기 위해서 weak_ptr을 이용한다.
    // weak_ptr은 shared_ptr 인스턴스가 소유하는 객체에 대한 접근은 제공하지만, ref count는 
    // 증가하지 않는 스마트 포인터이다.
    
    
    return 0;
}

https://docs.microsoft.com/ko-kr/cpp/standard-library/weak-ptr-class?view=vs-2019

* weak_ptr에서 참조하는 포인터의 소유권을 확인하기 위해서는, weak_ptr의 Expired()를 사용하면 된다.

물고 있는 포인터가 더이상 존재하지 않을 경우 weak_ptr의 Expired()는 true를 리턴한다.