소멸자 심층 탐구
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 104개 중 24번째.
소멸자는 객체가 소멸될 때 자동으로 실행되는 특수 멤버 함수입니다. 주요 역할은 동적으로 할당된 메모리, 파일 핸들 또는 네트워크 연결과 같이 객체가 수명 동안 획득한 리소스를 해제하는 것입니다.
소멸자는 클래스와 같은 이름 앞에 물결표 ~를 붙인 이름을 가집니다. 매개변수를 받지 않으며 반환 형식도 없습니다:
class FileHandler {
std::string filename;
int* buffer;
public:
FileHandler(std::string name, size_t size)
: filename(name), buffer(new int[size]) {
std::cout << "Opening " << filename << "\n";
}
~FileHandler() {
delete[] buffer;
std::cout << "Closing " << filename << "\n";
}
};소멸자는 다음과 같은 상황에서 자동으로 호출됩니다:
- 스택 객체가 스코프를 벗어납니다
- 힙에 할당된 객체에
delete가 호출됩니다 - 임시 객체의 수명이 끝납니다
void example() {
FileHandler f1("data.txt", 100); // 생성자 호출됨
FileHandler* f2 = new FileHandler("log.txt", 50);
delete f2; // f2에 대한 소멸자 호출됨
} // f1에 대한 소멸자 호출됨 (스코프를 벗어남)생성자와 달리 클래스에는 소멸자가 하나만 있을 수 있습니다. 소멸자를 오버로드할 수는 없습니다.
직접 정의하지 않으면 컴파일러가 특별한 작업을 하지 않는 기본 소멸자를 생성합니다. 기본 소멸자는 각 멤버를 단순히 소멸시킵니다. 리소스를 관리하는 클래스에서는 메모리 누수를 방지하기 위해 직접 작성해야 합니다.
챌린지
쉬움활성 사용자 세션을 추적하고 객체가 소멸될 때 범위를 벗어나거나 명시적으로 삭제되는 경우 소멸자가 리소스를 자동으로 정리하는 방식을 보여 주는 세션 관리자를 만들어 보겠습니다.
코드를 구성하기 위해 두 개의 파일을 만듭니다.
Session.h: 동적으로 할당된 데이터를 포함하는 활성 사용자 세션을 나타내는Session클래스를 정의합니다. 클래스에는 다음 항목이 있어야 합니다.- private 멤버:
username(문자열),sessionId(int), 사용자 작업을 추적하는activityLog라는 정수 배열에 대한 포인터, 그리고 배열 크기를 나타내는logSize - 사용자 이름, 세션 ID, 로그 크기를 인수로 받는 생성자. 힙에 활동 로그 배열을 할당하고, 모든 요소를 0으로 초기화한 다음
"Session <sessionId> started for <username>"을 출력해야 합니다. - 할당된 메모리를 해제하고
"Session <sessionId> ended for <username>"을 출력하는 소멸자 - 활동 코드를 다음 사용 가능한 위치에 저장하는
logActivity(int activityCode)메서드(현재 위치를 내부적으로 추적). 로그가 이미 가득 찬 경우 호출을 무시하여 개수가 로그 크기를 초과하지 않도록 합니다. - 기록된 활동의 개수를 반환하는
getActivityCount()메서드 - 사용자 이름을 반환하는
getUsername()메서드
- private 멤버:
main.cpp: 다양한 상황에서 소멸자가 동작하는 방식을 보여 줍니다. 입력에서 사용자 이름과 로그 크기를 읽습니다(각각 별도의 줄에 입력). 그런 다음 다음을 수행합니다.- 중괄호
{ }를 사용하여 범위 블록을 만들고, 그 안에서 입력된 사용자 이름, 세션 ID101, 입력된 로그 크기로 스택에 할당된Session을 생성합니다. 코드1과2로 두 개의 활동을 기록한 다음"Stack session activities: <count>"를 출력합니다. 블록이 끝나면 소멸자가 자동으로 실행되어야 합니다. - 블록 다음에
"Stack session destroyed"를 출력합니다. - 사용자 이름
"Guest", 세션 ID202, 로그 크기3으로new를 사용하여 힙에 할당된Session을 생성합니다. 코드5로 활동 하나를 기록하고,"Heap session activities: <count>"를 출력한 다음 명시적으로delete합니다. - 삭제한 다음
"Heap session destroyed"를 출력합니다.
- 중괄호
이 챌린지는 소멸자가 호출되는 두 가지 주요 방식을 보여 줍니다. 스택 객체가 범위를 벗어날 때는 자동으로 호출되고, 힙 객체를 삭제할 때는 수동으로 호출됩니다. 두 경로 모두 동적으로 할당된 활동 로그를 적절히 해제하여 메모리 누수를 방지해야 합니다.
#include "Session.h"를 사용하여 헤더 파일을 main.cpp에 포함하세요.
직접 해보기
#include <iostream>
#include <string>
#include "Session.h"
using namespace std;
int main() {
// 입력 읽기
string username;
int logSize;
getline(cin, username);
cin >> logSize;
// TODO: 중괄호 { }로 스코프 블록 만들기
// 블록 내부:
// - 입력 username, 세션 ID 101, 입력 log size로 스택에 할당된 Session 생성
// - 코드 1과 2로 두 개의 활동 로그
// - Print "Stack session activities: <count>"
// 블록이 끝나면 소멸자가 자동으로 실행됩니다
// TODO: After the block, print "Stack session destroyed"
// TODO: new를 사용하여 힙에 할당된 Session 생성
// - Username: "Guest", session ID: 202, log size: 3
// - 코드 5로 활동 하나 로그
// - Print "Heap session activities: <count>"
// - 세션 삭제
// TODO: After deletion, print "Heap session destroyed"
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 C++ 컴파일러