Qt에서 제공하는 메모리 할당 및 해제를 도와주는 포인터에 대해서 간단히 알아보자.
QScopedPointer 는 범위를 벗어나면 자동으로 가리키는 객체를 삭제한다.
void foo()
{
QScopedPointer<int> i(new int(42));
...
if (someCondition)
return; // int는 여기서 삭제된다.
} // 아니면 여기서 ...
함수의 종료 조건은 할당한 메모리를 누설하지 않는다.
그렇다면 포인터가 가리키는 객체에 어떻게 접근 할 수 있을까? QScopedPointer는 operator *
및 operator->
연사자가 구현되어있으므로 일반적인 포인터처럼 액세스 할 수 있다.
QScopedPointer<int> i(new int(42));
*i = 43;
할당 연산자 및 일부 연산자는 의도적으로 누락되었다. 대신 reset()
을 통해 포인터에 주소를 설정할 수 있다.
QScopedPointer<int> i(new int(42));
i = new int(43); // 컴파일되지 않음.
i.reset(new int(43)); // 문제없음. 가리키는 기존 개체(있는 경우)를 삭제하고 해당 포인터를 새로운 개체로 설정.
의도적으로 누락 된 또 다른 연산자는 포인터에 직접 액세스 할 수있는 연산자 T *()
이다.
int *foo()
{
QScopedPointer<int> i(new int(42));
...
return i; // 컴파일되지 않을 것이다.
}
범위가 지정된 포인터가 범위를 벗어나므로 반환하는 순간 객체가 삭제된다.
대신 QScopedPointer에게 작업이 완료되었고 힙 객체의 소유권을 가진다는 것을 take()
를 호출하여 알릴 수 있다.
int *foo()
{
QScopedPointer<int> i(new int(42));
...
if (someError)
return 0; // 여기에서 삭제된다.
return i.take(); // 힙에 객체가 남아 있음.
}
new []
연산자 또는 malloc()
으로 할당 하는경우는 어떤지보자. 이러한 경우 해제를 정의하는 두 번째 템플릿 매개 변수를 이용한다.
QScopedPointer<int, QScopedPointerPodDeleter> pod(static_cast<int *>(malloc(sizeof int)));
QScopedPointer가 범위를 벗어난 경우 QScopedPointerPodDeleter 에서 free 된다.
delete []
연산자 처럼 가리키는 객체를 삭제하는 QScopedArrayPointer 도 있다.
void foo()
{
QScopedArrayPointer<int> i(new int[10]);
i[2] = 42;
...
return; // 여기서 정수 배열은 삭제된다.
}