C++ 프로그래밍
C++ unique_ptr을 응용하여 자동으로 핸들을 닫는 클래스 만들기
하늘흐늘
2024. 4. 15. 19:38
반응형
C++을 사용하여 프로그램을 하다보면 핸들을 많이 다루게 됩니다. 특히 I/O 관련 작업을 할 때나 윈도우 API를 사용할 때 파일을 비롯한 각종 핸들(HANDLE)을 사용하게 됩니다. 이 때 다 사용한 핸들을 닫아주지 않으면 핸들 관련 누수(Leak)가 생기게 됩니다.
이럴 경우 unique_ptr을 이용하여 구간에서만 핸들을 사용하고 다 사용한 후에는 자동으로 핸들을 자동으로 닫게하면 위에서 말한 문제가 일어날 가능성이 적어지게 됩니다.
아래 예제 코드를 살펴보겠습니다.
#include <iostream>
#include <cstdio>
using namespace std;
struct FileCloser {
void operator()(FILE* file) const {
if (file) {
fclose(file);
std::cout << "File closed.\n";
}
}
};
typedef std::unique_ptr<FILE, FileCloser> ScopeHandle;
int main(int argc, char* argv[])
{
FILE* file = nullptr;
fopen_s(&file, "test.txt", "w");
if (!file) {
std::cerr << "Failed to open file.\n";
return 1;
}
ScopeHandle filePtr(file);
fprintf(filePtr.get(), "Hello, world!\n");
// 파일 핸들이 범위를 벗어나면 자동으로 닫힘
return 0;
}
실행 결과는 아래와 같습니다.
File closed.
소스 코드는 간단한 예제를 위하여 C 라이브러리의 FILE을 예제로 보여주었습니다. 예제에서 unique_ptr을 사용하여 ScopeHandle을 정의하여 사용하였습니다. unique_ptr에 템플릿 인자 2 개 주는 것이 조금 어색해 보일 수 있는데 2번째 인자는 해당 객체에 대한 삭제자(delete)라고 보시면 됩니다. 삭제자는 리소스 해제 과정의 커스터마이징에 사용된다고 보시면 됩니다. 이 예제에서는 operator()(File* file)가 unique_ptr이 가지고 있는 객체의 포인터를 파라메터로 하여 호출된다고 보시면 됩니다.
예제 코드에서 file에 대한 핸들을 ScopeHandle가 관리하게 하여 함수가 끝나면 자동으로 파일을 close하게 만들었습니다.
예제에서는 C 라이브러리의 FILE을 이용하였지만 조금만 수정하면 윈도우 API의 각종 HANDLE에 대해서도 응용할 수 있습니다.
반응형