본문 바로가기

C++

[C++] 스마트 포인터 - auto_ptr

auto_ptr은 동적 할당한 인스턴스를 자동으로 삭제한다.

 

#include <iostream>
using namespace std;

class myClass
{
public:
	myClass() { cout << "myClass()" << endl; };
	~myClass() { cout << "~myClass()" << endl; };
};

int main() {

	cout << "main() start" << endl;
	{	//이 블록 범위를 벗어나면 자동으로 소멸자 호출
		auto_ptr<myClass> ptr(new myClass);
	}
	cout << "main() end" << endl;

	return 0;
}

 

결과값:

main() start
myClass()
~myClass()
main() end

 

블록 스코프 안에 auto_ptr로 객체를 생성하자 main() 함수가 끝나기 전에 소멸자가 호출되는 것을 확인할 수 있다. 자동으로 동적 할당한 메모리를 해제해주니 편리하다.

 

하지만, 배열로 선언하면 어떻게 될까?

auto_ptr<myClass> ptr(new myClass[3]);

 

결과값:

main() start
myClass()
myClass()
myClass()
~myClass()
에러, 프로그램 종료

 

배열로 동적 할당을 하면 배열로 해제해야 한다. 그러나 첫 번째 객체만 소멸하고 나머지는 소멸하지 않았다. 배열로 delete 하지 않았기 때문이다.

 

 

다음은 auto_ptr로 얕은 복사를 수행한 예이다.

 

#include <iostream>
using namespace std;

class myClass
{
public:
	myClass() { cout << "myClass()" << endl; };
	~myClass() { cout << "~myClass()" << endl; };
	void TestFunc() {};
};

int main() {

	//myClass 동적할당
	auto_ptr<myClass> ptr(new myClass);
	cout << ptr.get() << endl;

	//ptr_new가 ptr 얕은 복사
	auto_ptr<myClass> new_ptr = ptr;
	
	//얕은 복사후 원본주소 출력
	cout << ptr.get() << endl;

	//에러
	//ptr->TestFunc();

	return 0;
}

 

결과값:

myClass()
0138DD80
00000000
~myClass()

 

얕은 복사 후 원본 주소를 출력하니 NULL로 초기화되었다. 얕은 복사를 수행해야 하는데 이동하는 결과나 나왔다. 이러한 auto_ptr은 오래전부터 있었던 스마트 포인터이고 이런 문제점을 보안하기 위해 나온 것이 shared_ptr이다. 배열과 얕은 복사의 문제점 때문에 auto_ptr은 가급적 사용하지 않는 것이 바람직하다고 한다.