#include <iostream>
using namespace std;
// 1) 개념: -> 연산자를재정의해서다른객체의포인터역할을하는객체.
// 2) 원리: -> 연산자재정의
// 3) 장점: 자원관리를자동으로할수있다.
// 4) explicit 생성자SPTR<int> p2( new int ); 로생성해야한다.
// 5) Owner Ship 관리- 중요!
class Test
{
public:
int x;
void foo() { cout << "Test::foo" << endl; }
};
template<typename T> class SPTR
{
T* _obj;
int* pCount; // 참조카운팅을하기위해
public:
explicit SPTR( T* p ) : _obj(p)
{
pCount = new int(1); // 힙에카운팅을만든다.!!
}
~SPTR()
{
if( --(*pCount) == 0 )
{
delete _obj;
delete pCount;
}
} // 자동삭제가능.
T* operator->() { return _obj; }
T& operator *() { return *_obj; }
// 참조개수기법으로구현한복사생성자
SPTR( const SPTR& s )
{
_obj = s._obj;
pCount = s.pCount;
++(*pCount);
}
/*
// 소유권이전
SPTR( SPTR<T>& s )
{
_obj = s._obj;
s.obj = 0;
}
*/
};
void main()
{
SPTR<Test> p1( new Test );
SPTR<Test> p2 = p1;
}
/* 1) ~ 4)
void main()
{
//SPTR<int> p2 = new int; // explicit 생성자라서error
SPTR<int> p2( new int );
*p2 = 20;
cout << *p2 << endl;
//Test* p = new Test;
//SPTR<Test> p = new Test; // SPTR P( new Test );
SPTR<Test> p( new Test ); // SPTR p( new Test );
(*p).x = 10;
cout << (*p).x << endl;
p->foo(); // (p.operator->())foo() 이지만
// 컴파일러가(p.operator->())->foo()로해석해준다.
}
*/
/* 스마트포인터에장점!!
void ReleaseFucntion( FILE * f)
{
fclose(f);
}
void foo()
{
//int* p = new int;
SPTR<int> p( new int ); // Resource Acqusion Is Initialize (RAII)
{
//fclose 를대신할ReleaseFucntion !!
//생성자에서함수포인터를받아서delete할때ReleaseFucntion 호출
//SPTR<FILE> p2( fopen( "a.txt", "wt" ), ReleaseFucntion );
SPTR<FILE> p2( fopen( "a.txt", "wt" ), fclose );
}
if ( n == 0 )
{
//delete p;
return;
}
//delete p;
}
*/