Menu
Coddy logo textTech

C++의 RAII

Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 104개 중 16번째.

RAII(Resource Acquisition Is Initialization)는 resource 관리를 object의 수명에 연결하는 기본적인 C++ 관용구입니다. 아이디어는 간단합니다. constructor에서 resource를 획득하고 destructor에서 해제합니다.

object가 생성되면 필요한 모든 리소스를 획득합니다. object가 스코프를 벗어나면 destructor가 automatically 해당 리소스를 해제합니다. 따라서 예외가 발생하더라도 정리가 보장됩니다.

class FileHandler {
    std::FILE* file;
public:
    FileHandler(const char* filename) {
        file = std::fopen(filename, "r");  // 리소스 획득
    }
    
    ~FileHandler() {
        if (file) std::fclose(file);       // 리소스 해제
    }
};

RAII를 사용하면 정리 작업을 잊는 일이 없습니다:

void processFile() {
    FileHandler handler("data.txt");  // 리소스 획득됨
    // 파일로 작업...
    // 여기서 예외가 발생해도 소멸자는 여전히 실행됩니다!
}   // 리소스가 자동으로 해제됨

스마트 포인터는 실제로 작동하는 RAII의 완벽한 예입니다. unique_ptr는 생성자에서 힙 메모리의 소유권을 획득하고 소멸자에서 이를 삭제합니다. 여러분은 이미 자신도 모르는 사이에 RAII를 사용하고 있었습니다!

RAII는 모든 resource에 적용됩니다. 메모리, file 핸들, 네트워크 연결, 뮤텍스 또는 데이터베이스 연결이 이에 해당합니다. resource를 object로 감싸면 C++는 결정적인 정리를 보장하고, 메모리 누수와 댕글링 핸들과 같은 버그의 전체 범주를 제거합니다.

challenge icon

챌린지

쉬움

RAII를 사용하여 네트워크와 유사한 connection의 수명 주기를 automatically 처리하는 connection manager를 만들어 봅시다. connection이 생성되면 "open"되고, scope를 벗어나면 automatically "close"되어야 합니다. 수동 정리는 필요하지 않습니다!

코드를 구성하기 위해 두 개의 file을 만듭니다:

  • Connection.h: RAII 원칙을 사용하여 connection resource를 관리하는 Connection class를 define합니다. class에는 다음이 있어야 합니다:
    • connection을 식별하기 위한 private connectionId attribute (string)
    • connection state를 추적하기 위한 private isOpen attribute (bool)
    • connection ID를 인수로 받고, isOpen을 true로 설정하며, "Opening connection: <id>"를 print하는 constructor
    • connection이 open 상태인지 확인하고, isOpen을 false로 설정하여 close한 다음, "Closing connection: <id>"를 print하는 destructor
    • connection이 open 상태일 때 "[<id>] Sending: <message>"를 print하는 send(string message) method
    • connection ID를 반환하는 getId() method
  • main.cpp: input에서 connection ID와 message를 읽어 RAII가 자동 정리를 보장하는 방식을 보여 줍니다. 그런 다음:
    • curly braces { }를 사용하여 scope를 만듭니다.
    • 그 scope Inside에서 input ID를 사용하여 stack에 Connection object를 Create합니다.
    • connection을 사용하여 input message를 send합니다.
    • scope가 end되도록 Let합니다 (connection은 automatically close되어야 합니다).
    • scope After에 "Connection out of scope"를 Print합니다.

RAII의 장점은 connection을 close하는 것을 기억할 필요가 없다는 것입니다. object가 scope를 벗어날 때 destructor가 automatically 처리합니다. 이 pattern은 코드에서 예상하지 못한 일이 발생하더라도 resource leak을 방지합니다.

#include "Connection.h"를 사용하여 main.cpp에 header file을 include합니다.

직접 해보기

#include <iostream>
#include <string>
#include "Connection.h"

using namespace std;

int main() {
    string connectionId;
    string message;
    
    // 입력 읽기
    cin >> connectionId;
    cin.ignore();
    getline(cin, message);

    // TODO: 중괄호 { }를 사용하여 스코프 생성
    // 스코프 내부:
    //   - connectionId로 스택에 Connection 객체 생성
    //   - connection을 사용하여 message 전송
    // 스코프가 끝나도록 함 (소멸자가 자동으로 호출됨)

    // TODO: After the scope ends, print "Connection out of scope"

    return 0;
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 C++ 컴파일러