이번에는 Smart Pointer 이다. new 해서 사용해도 delete 할필요가 없다.
Java 나 C# 에서와 같이 자기참조 카운터를 관리하고 카비지 컬렉터도 가지고 있다. 물론 다중스레드에서도 안전하다.
#include <boost/tr1/tr1/memory> 해더가 필요하다.
기본 사용법
int _tmain(int argc, _TCHAR* argv[]) { std::tr1::shared_ptrsp1(new int); *sp1 = 1; // 값 대입 std::tr1::shared_ptr sp2(new int(5)); std::cout << "sp1 의 값:" << *sp1 << std::endl; std::cout << "sp1 의 주소:" << sp1 << std::endl; std::cout << "sp2 의 값:" << *sp2 << std::endl; std::cout << "sp2 의 주소:" << sp2 << std::endl; std::cout << std::endl; *sp1 = *sp2; //call by value sp2.reset(new int(9)); std::cout << "sp1 의 값:" << *sp1 << std::endl; std::cout << "sp1 의 주소:" << sp1 << std::endl; std::cout << "sp2 의 값:" << *sp2 << std::endl; std::cout << "sp2 의 주소:" << sp2 << std::endl; std::cout << std::endl; sp1 = sp2; //call by reference *sp1 = 7; std::cout << "sp1 의 값:" << *sp1 << std::endl; std::cout << "sp1 의 주소:" << sp1 << std::endl; std::cout << "sp2 의 값:" << *sp2 << std::endl; std::cout << "sp2 의 주소:" << sp2 << std::endl; return 0; } 실행결과: sp1 의 값:1 sp1 의 주소:00032F78 sp2 의 값:5 sp2 의 주소:00032FE8 sp1 의 값:5 sp1 의 주소:00032F78 sp2 의 값:9 sp2 의 주소:000313D8 sp1 의 값:7 sp1 의 주소:000313D8 sp2 의 값:7 sp2 의 주소:000313D8
메모리 해제를 사용자 정의 함수로 처리가 가능하다.
class deleter { public: void operator()(int *p) { std::cout << "delete_operator" << std::endl; delete p; } static void Deleter(int* p) { std::cout << "delete_static_method" << std::endl; delete p; } }; void deleter_method(int *p) { std::cout << "delete_method" << std::endl; delete p; } int _tmain(int argc, _TCHAR* argv[]) { std::tr1::shared_ptrsp1(new int(5), deleter()); std::tr1::shared_ptr sp2(new int(5), deleter_method); std::tr1::shared_ptr sp3(new int(5), deleter::Deleter); return 0; } 실행결과: delete_static_method delete_method delete_operator
응용편~ 요런걸 사용해도 메모리 해제의 부담이 없다.
class Animal_Interface { public: virtual void Crying() = 0; }; class Animal_dog : public Animal_Interface { public: void Crying() {std::cout << "멍멍멍 !!!" << std::endl;}; }; class Animal_cat : public Animal_Interface { public: void Crying() {std::cout << "야옹~" << std::endl;}; }; int _tmain(int argc, _TCHAR* argv[]) { std::tr1::shared_ptrdog(new Animal_dog); std::tr1::shared_ptr cat(new Animal_cat); dog->Crying(); cat->Crying(); return 0; } 실행결과: 멍멍멍 !!! 야옹~
주의 할점 !!! shared_ptr 을 사용할때 하나의 포인터를 두개의 shared_ptr 이 참조하면 두번 삭제(delete) 하므로 crash를 발생할 수 있다.
void Crash_Double_Ref_1() { int* p = new int; std::tr1::shared_ptrsp1(p); std::tr1::shared_ptr sp2(p); } //함수가 종료되면 스레드 스텍에서 sp1 이 p 를 제거(delete) 하고 //sp2 가 또 p 를 제거 하므로 sp2 가 제거할때 crash 발생한다. void Crash_Double_Ref_2(int* p) { std::tr1::shared_ptr sp1(p); } //함수가 종료되면 sp1 이 p 를 제거(delete)한다. int _tmain(int argc, _TCHAR* argv[]) { Crash_Double_Ref_1(); int* p = new int; Crash_Double_Ref_2(p); delete p; //Crash_Double_Ref_2 가 p 를 제거 했기 때문에 delete 할때 crash return 0; }
하나의 포인터를 두개의 shared_ptr 로 사용한던지, 다른 포인터 변수에서 생성된 포인터를 사용하는 일은 습관적으로 하지 말것을 권장 !!!
'Library' 카테고리의 다른 글
TR1 유용한 클래스/함수 (4-1) ... mem_fn 템플릿 (0) | 2010.11.08 |
---|---|
TR1 유용한 클래스/함수 (3) ... UnOrdered Associative Containers (0) | 2010.01.27 |
TR1 유용한 클래스/함수 (1) ... tuple (0) | 2010.01.14 |
C++ TR1 설치 (0) | 2010.01.08 |
Apache Log4cxx 0.10.0 윈도우에서 빌드 하기 (2) | 2008.07.28 |