소멸자 심층 탐구
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 104개 중 24번째.
destructor는 객체가 destroyed될 때 automatically 실행되는 특수 멤버 함수입니다. 주요 역할은 객체가 수명 동안 획득한 리소스(예: 동적으로 allocated된 메모리, 파일 핸들 또는 네트워크 연결)를 해제하는 것입니다.
destructor는 class와 같은 이름을 가지며, 앞에 물결표 ~가 붙습니다. 매개변수를 받지 않으며 반환 형식도 없습니다:
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";
}
};Destructor는 다음 상황에서 called automatically됩니다:
- 스택 객체는 범위를 벗어납니다
- 힙에 할당된 객체에
delete가 호출됩니다 - 임시 객체의 수명이 ends
void example() {
FileHandler f1("data.txt", 100); // 생성자 호출됨
FileHandler* f2 = new FileHandler("log.txt", 50);
delete f2; // f2에 대한 소멸자 호출됨
} // f1에 대한 소멸자 호출됨 (스코프를 벗어남)생성자와 달리 클래스에는 하나의 destructor만 있을 수 있습니다. 이를 오버로드할 수 없습니다.
하나를 정의하지 않으면 컴파일러가 특별한 작업을 하지 않는 기본 destructor를 생성합니다. 즉, 각 멤버를 단순히 소멸시킵니다. 리소스를 관리하는 클래스의 경우 메모리 누수를 방지하려면 직접 작성해야 합니다.
챌린지
쉬움범위를 벗어나거나 명시적으로 삭제되는 경우에 관계없이, 활성 사용자 세션을 추적하고 객체가 소멸될 때 소멸자가 리소스를 automatically 정리하는 방식을 보여 주는 세션 관리자를 만들어 보겠습니다.
코드를 구성하기 위해 두 개의 파일을 만듭니다:
Session.h: 동적으로 할당된 데이터를 사용하는 활성 사용자 세션을 나타내는Sessionclass를 define합니다. class에는 다음이 포함되어야 합니다:- Private 멤버:
username(문자열),sessionId(정수), 사용자 작업을 추적하는activityLog라는 정수 array에 대한 포인터, 그리고 array 크기를 위한logSize - username, 세션 ID, log size를 인수로 받는 Constructor. activity log array를 heap에 allocate하고, 모든 elements를 0으로 초기화한 다음
"Session <sessionId> started for <username>"을 출력해야 합니다. - 할당된 메모리를 해제하고
"Session <sessionId> ended for <username>"을 출력하는 Destructor - activity code를 다음 available 슬롯에 저장하는
logActivity(int activityCode)method (current position은 내부적으로 추적) - 기록된 activities의 개수를 반환하는
getActivityCount()method - username을 반환하는
getUsername()method
- Private 멤버:
main.cpp: 다양한 상황에서 Destructor 동작을 보여 줍니다. 입력에서 username과 log size를 읽습니다(각각 별도의 줄에 입력). 그런 다음:- curly braces
{ }를 사용해 scope block을 만들고, 그 안에 입력된 username, 세션 ID101, 입력된 log size를 사용하여 stack에 allocate된Session을 Create합니다. codes1과2로 두 개의 activities를 기록한 다음"Stack session activities: <count>"를 출력합니다. block이 끝나면 Destructor가 automatically 실행되어야 합니다. - block 다음에
"Stack session destroyed"를 출력합니다. - username
"Guest", 세션 ID202, log size3을 사용하여new로 heap에 allocate된Session을 Create합니다. code5로 activity 하나를 기록하고,"Heap session activities: <count>"를 출력한 다음 명시적으로delete합니다. - deletion 후에
"Heap session destroyed"를 출력합니다.
- curly braces
이 challenge는 Destructor가 호출되는 두 가지 주요 방식을 보여 줍니다. stack 객체가 scope를 벗어날 때 automatically 호출되는 방식과 heap 객체를 delete할 때 수동으로 호출되는 방식입니다. 두 경로 모두 memory leak을 방지하기 위해 dynamically allocate된 activity log를 올바르게 해제해야 합니다.
#include "Session.h"를 사용하여 main.cpp에 header file을 포함하세요.
직접 해보기
#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++ 컴파일러