개발/C++

[C++] shared_ptr

hojak99 2016. 12. 26. 20:10

스마트 포인터 중 하나인 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

*/




반응형