auto_ptr은 스마트포인터 중에서 가장 오래된 스마트포인터입니다.
구형인만큼 auto_ptr은 사용에 불편함이 많아 사용하지 않는 것이 바람직한데요.
왜 불편하고 사용하지 말라고 하는지 하나씩 살펴보도록 하겠습니다.
auto_ptr
- C++ 표준 라이브러리 헤더 파일 **
**을 include 해야 사용이 가능합니다. - 스마트 포인터인 auto_ptr은 템플릿으로 구현되어 있습니다.
- auto_ptr은 동적 할당한 인스턴스를 자동으로 삭제합니다.
- 배열은 사용이 불가능합니다.
- 단순 대입 연산 시, 값이 복사되지 않고 “이전”하게 됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<iostream>
#include<memory>
using namespace std;
class TEST
{
public:
TEST()
{
cout << "생성자 호출" << endl;
}
~TEST()
{
cout << "소멸자 호출" << endl;
}
};
int main()
{
cout << "Begin" << endl;
{
// 블록을 벗어나면 인스턴스가 자동으로 삭제됩니다.
auto_ptr<TEST> autoPtr(new TEST);
}
cout << "End" << endl;
}
// 출력 결과
Begin
생성자 호출
소멸자 호출
End
문제점 1 - 배열 사용 불가
auto_ptr은 배열에 사용이 불가능합니다.
아래 예제 코드를 먼저 살펴보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main()
{
cout << "Begin" << endl;
{
auto_ptr<TEST> autoPtr(new TEST[3]);
}
cout << "End" << endl;
}
// 출력 결과
Begin
생성자 호출
생성자 호출
생성자 호출
소멸자 호출
---> 런타임 에러 발생으로 종료
auto_ptr을 통해 크기가 3인 배열을 생성해 주었고 생성자가 3회 호출되는 것을 볼 수 있습니다.
하지만 블록이 끝난 후 소멸자는 3개가 호출되지 않고 하나만 호출되는 것을 볼 수 있는데요.
이를 통해서 auto_ptr은 소멸할 때 배열에 대한 처리가 되어있지 않음을 알 수 있습니다.
정리하면, “auto_ptr은 단일 객체에 대한 처리만 지원한다“라고 볼 수 있습니다.
문제점 2 - 동일한 메모리를 가리키는 auto_ptr 객체는 하나만 존재해야 한다
auto_ptr은 동일한 메모리를 가리키는 auto_ptr 객체는 하나만 존재해야 합니다.
아래 코드를 살펴보면 autoPtr2는 autoPtr 값을 복사해 초기화하고 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
auto_ptr<TEST> autoPtr(new TEST());
auto_ptr<TEST> autoPtr2;
autoPtr2 = autoPtr;
autoPtr2->Print();
autoPtr->Print();
}
// 출력 결과
생성자 호출
Print
---> 런타임 에러 발생으로 종료
정상적으로 값이 복사되었다면 autoPtr과 autoPtr2는 동일한 메모리(객체)를 가리키고 있는데요.
실제로 돌려보면 autoPtr은 NULL 상태가 되어 있습니다.
즉,
동일한 메모리를 가리키는 auto_ptr 객체는 하나이기 때문에
autoPtr이 가리키는 객체를 autoPtr2에 복사함에 따라 기존 소유자인 autoPtr은 소유권을 잃게 됩니다.
그러므로 소유권을 잃은 autoPtr은 NULL이 되게 됩니다.
**auto_ptr
autoPtr2 = autoPtr