스마트 포인터 중 하나인 shared_ptr 에 대해서 알아보자.
shared_ptr은 reference-counting smart pointer 중의 하나이다.
std :: shared_ptr은 포인터를 통해 객체의 공유 소유권을 유지하는 스마트 포인터이다.
여러 shared_ptr 객체가 동일한 객체를 소유 할 수 있고, 객체가 파괴되고 다음 중 하나가 발생하면 메모리가 해제된다.
- 마지막으로 남아있는 shared_ptr을 소유하고 있는 객체가 파괴된다.
- 마지막으로 남아있는 shared_ptr을 소유하고 있는 객체가 다른 포인터에 의해 operator=
또는 reset()으로 할당된 경우하여 객체가 파괴된다.
생성되는 동안 shared_ptr에 제공되는 delete-expression 이나 custom deleter를 사용.
shared_ptr은 다른 객체에 대한 포인터를 저장하는 동안 객체의 소유권을 공유할 수 있으며 이 기능은 개체를 소유하는 동안 개체를 가리키는 데 사용할 수 있다. 저장된 포인터는 get(), 역참조와 비교 연산자에 의해 액세스 된 포인터이다. 사용된 카운터가 0이 되면 관리되는 포인터는 deleter에 전달된다.
멤버 함수
get : 저장된 포인터를 반환한다.
[ returns the stored pointer ]
operator*, operator-> : 저장된 포인터를 역참조한다.
[ dereferences the stored pointer ]
operator[] : 저장된 배열에 대해 인덱스로 접근할 수 있도록 한다.
[ provides indexed access to the stored array ]
use_count : 동일하게 관리되는 객체를 참조하는 shared_ptr의 수를 반환한다.
[ returns the number of shared_ptr objects referring to the same managed object ]
unique : 관리되는 객체가 오직 현재 shared_ptr 인스턴스에서만 관리되는지 확인한다.
[ checks whether the managed object is managed only by the current shared_ptr instance ]
operator bool : 저장된 포인터가 null이 아닌지 체크한다.
[ checks if the stored pointer is not null ]
owner_before : 공유 포인터의 소유자 기반 순서를 제공한다.
[ provides owner-based ordering of shared pointers ]
shared_ptr의 사용법은 다음과 같다.
std::shared_ptr<int> count = std::shared_ptr<int>(new int);
shared_ptr은 참조 카운팅 방식이기 때문에 내부적으로 카운팅을 유지해서 자원의 참조 갯수를 센다. shared_ptr의 문제점은 동적 배열로 생성된 경우 판단을 할 수 없다는 것이다.
//////
#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<int> count(new int[5], std::default_delete<int>());
for (int i = 0; i < 5; ++i) {
count[i] = i; //오류
}
return 0;
}
shared_ptr에서 레퍼런스 카운트를 증가시키는 방법은 함수의 인자로 넘기거나 값의 대입으로 인한 복사가 일어날 때 (이 때 shared_ptr 타입으로 대입이 일어날 때만) 증가한다.
#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<int> count(new int);
std::cout <<"count : "<<count.use_count() << std::endl;
std::shared_ptr<int> count1(count);
std::cout <<"count : "<< count.use_count()<<", count1 : " <<count1.use_count()<< std::endl;
std::shared_ptr<int> count2 = count1;
std::cout << "count : " << count.use_count() << ", count1 : " << count1.use_count() <<", count2 : "<<count2.use_count()<< std::endl;
return 0;
}
/*
출력값 :
count : 1
count : 2, count1 : 2
count : 3, count1 : 3, count2 : 3
*/
그리고 레퍼런스 카운트를 감소될 때에는 함수의 인자로 넘겨준 뒤 해당 함수가 종료될 때, 값을 넘겨준 객체가 삭제될 때, 강제로 삭제될 때이다.
========
#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<int> count(new int);
std::cout <<"count : "<<count.use_count() << std::endl;
std::shared_ptr<int> count1(count);
std::cout <<"count : "<< count.use_count()<<", count1 : " <<count1.use_count()<< std::endl;
std::shared_ptr<int> count2 = count1;
std::cout << "count : " << count.use_count() << ", count1 : " << count1.use_count() <<", count2 : "<<count2.use_count()<< std::endl;
count.~shared_ptr();
count1.~shared_ptr();
std::cout << "\ncount : " << count.use_count() << ", count1 : " << count1.use_count() << ", count2 : " << count2.use_count() << std::endl;
return 0;
}
/*
출력값 :
count : 1
count : 2, count1 : 2
count : 3, count1 : 3, count2 : 3
count : 1, count1 : 1, count2 : 1
*/