1. auto_ptr클래스는 예외가 발생했을 경우 리소스릭을 피하기 위해 STL이 제공하는 스마트 포인터의 한 종류이다.
즉 자신이 가리키는 객체에 대한 소유자로서 행동하는 포인터이다. auto_ptr이 파괴된다면 소유하고 있던 객체도 자동으로 파괴되는 것이다.
통상적으로 auto_ptr클래스는 할당 연산자(=)를 통해서 초기화를 할 수 없다.
ex)
std::auto_ptr<classa>ptr1(new classa);
std::auto_ptr<classa>ptr2(new classa);
ptr2 = ptr1; //auto_ptr을 할당하면 ptr2가 소유한 객체를 소멸하게 되고 소유권이 ptr1에서 ptr2로 이전된다.
// ptr1 null상태
2. 위험성있는 코드
ex1)
template <class T>
void bad_print(std::auto_ptr<T> p) //넘어온 인자의 소유권을 p가 가짐
{
...
} //종료하면서 p가 참조하는 객체를 삭제!! -> 심각한 런타임 에러
ex2)
std::auto_ptr<int> f()
{
3. 클래스안에서 auto_ptr을 사용함으로써 리소스 릭을 피할 수 있다.
일반적으로 생성자가 완전히 완료된 경우에만 소멸자가 호출된다는 사실을 명심!!
class ClassB{
private:
ClassA* ptr1; //포인터 멤버
ClassA* ptr2;
public:
//포인터를 초기화하는 생성자에서 두번째 new에서 예외를 던지면 리소스 릭의 원인이 될수 있다.
ClassB(ClassA val1,ClassA val2)
: ptr1(new ClassA(val1)),ptr2(new ClassA(val2)){ }
-> 개선
class ClassB{
private:
const std::auto_ptr<ClassA>ptr1; //auto_ptr멤버
const std::auto_ptr<ClassA>ptr2;
public:
ClassB(ClassA val1, ClassA val2)
: ptr1(new ClassA(val1)),ptr2(new ClassA(val2)){ }
4. auto_ptr의 잘못된 사용사례
a) auto_ptr은 소유권을 공유할 수 없다.
첫번째 auto_ptr이 삭제될때 객체가 파괴됨으로써 두번째 auto_ptr은 파괴된 객체를 가리킬수있따. 심각한 에러
b) auto_ptr은 배열 타입을 지원하지 않는다.
컨테이너 클래스를 쓰세요
c) auto_ptr은 범용 스마트 포인터가 아니다.
레퍼런스 카운트 개념을 사용하지 않는다.
d) auto_ptr은 표준 컨테이너 클래스와 함께 사용될 수 없다.
컨테이너 클래스의 원소로써 auto_ptr은 절대로 사용해서는 안된다.
e) const auto_ptr으로 사용하라..
즉 자신이 가리키는 객체에 대한 소유자로서 행동하는 포인터이다. auto_ptr이 파괴된다면 소유하고 있던 객체도 자동으로 파괴되는 것이다.
통상적으로 auto_ptr클래스는 할당 연산자(=)를 통해서 초기화를 할 수 없다.
ex)
std::auto_ptr<classa>ptr1(new classa);
std::auto_ptr<classa>ptr2(new classa);
ptr2 = ptr1; //auto_ptr을 할당하면 ptr2가 소유한 객체를 소멸하게 되고 소유권이 ptr1에서 ptr2로 이전된다.
// ptr1 null상태
2. 위험성있는 코드
ex1)
template <class T>
void bad_print(std::auto_ptr<T> p) //넘어온 인자의 소유권을 p가 가짐
{
...
} //종료하면서 p가 참조하는 객체를 삭제!! -> 심각한 런타임 에러
ex2)
std::auto_ptr<int> f()
{
const std::auto_ptr<int> p(new int); //소유권의 이전이 불가능
std::auto_ptr<int> q(new int); //소유권이전이 가능
*p = 42; //ok
bad_print(p); //컴파일 에러
*p = *q; //ok
p = q; //컴파일 에러
return p;//컴파일 에러
}
std::auto_ptr<int> q(new int); //소유권이전이 가능
*p = 42; //ok
bad_print(p); //컴파일 에러
*p = *q; //ok
p = q; //컴파일 에러
return p;//컴파일 에러
}
3. 클래스안에서 auto_ptr을 사용함으로써 리소스 릭을 피할 수 있다.
일반적으로 생성자가 완전히 완료된 경우에만 소멸자가 호출된다는 사실을 명심!!
class ClassB{
private:
ClassA* ptr1; //포인터 멤버
ClassA* ptr2;
public:
//포인터를 초기화하는 생성자에서 두번째 new에서 예외를 던지면 리소스 릭의 원인이 될수 있다.
ClassB(ClassA val1,ClassA val2)
: ptr1(new ClassA(val1)),ptr2(new ClassA(val2)){ }
-> 개선
class ClassB{
private:
const std::auto_ptr<ClassA>ptr1; //auto_ptr멤버
const std::auto_ptr<ClassA>ptr2;
public:
ClassB(ClassA val1, ClassA val2)
: ptr1(new ClassA(val1)),ptr2(new ClassA(val2)){ }
4. auto_ptr의 잘못된 사용사례
a) auto_ptr은 소유권을 공유할 수 없다.
첫번째 auto_ptr이 삭제될때 객체가 파괴됨으로써 두번째 auto_ptr은 파괴된 객체를 가리킬수있따. 심각한 에러
b) auto_ptr은 배열 타입을 지원하지 않는다.
컨테이너 클래스를 쓰세요
c) auto_ptr은 범용 스마트 포인터가 아니다.
레퍼런스 카운트 개념을 사용하지 않는다.
d) auto_ptr은 표준 컨테이너 클래스와 함께 사용될 수 없다.
컨테이너 클래스의 원소로써 auto_ptr은 절대로 사용해서는 안된다.
e) const auto_ptr으로 사용하라..