소멸자(Destructor)란?
소멸자는 객체가 정해진 스코프(Scope)를 벗어나거나 또는 명시적으로 delete delete[] 되었을 때 호출되는 멤버 함수입니다.
소멸자는 클래스의 이름과 동일한 이름으로 선언되며 이때 이름 앞에 ~ 문자가 prefix로 추가됩니다.
class Human
{
char* name;
int age;
~Human()
{
}
};
코드 | 비고 | |
소멸자는 |
소멸자를 명시적으로 정의하지 않으면 컴파일 과정에서 디폴트 소멸자가 제공됩니다.
일부 클래스의 경우 컴파일러가 제공하는 디폴트 소멸자로 충분하지만, 어떤 클래스의 경우 멤버 변수 등에 의해 참조되고 있는 인스턴스를 소거하는 과정이 필요합니다.
class Human
{
char* name;
int age;
Human(char* _name)
{
name = _name;
}
~Human()
{
delete[] name;
}
};
위 예시에서는 char* name 멤버 변수에 동적 할당된 메모리 공간을 소멸자에서 delete합니다.
소멸자의 호출 시점
소멸자가 호출되는 시점은 다시 말해 인스턴스에 대한 생명 주기-라이프 사이클(Life cycle)입니다.
#include <iostream>
#include <cstring>
using namespace std;
void test()
{
class Human
{
char* name;
int age;
public:
Human(char* _name)
{
name = _name;
}
~Human()
{
delete[] name;
std::cout << "~Human destructor invoked" << std::endl;
}
};
char* name = new char[100];
strcpy(name, "foo");
Human m = Human(name);
}
int main()
{
test();
}
코드 | 비고 | |
Human 객체를 생성합니다. 곧 이어 Scope를 벗어나 객체가 소멸됩니다. |
단순 블록 범위에 존재하는 객체는 Stack 메모리에서 관리됩니다.
Stack에서 관리되는 객체는 해당 Scope를 벗어나는 시점에 자동으로 소멸자가 호출됩니다.
~Human destructor invoked
반면 동적 할당된 객체는 Heap 메모리에서 관리됩니다.
#include <iostream>
#include <cstring>
using namespace std;
void test()
{
class Human
{
char* name;
int age;
public:
Human(char* _name)
{
name = _name;
}
~Human()
{
delete[] name;
std::cout << "~Human destructor invoked" << std::endl;
}
};
char* name = new char[100];
strcpy(name, "foo");
Human* m = new Human(name);
}
int main()
{
test();
}
코드 | 비고 | |
Human 객체를 동적 할당하고 포인터에 초기화합니다. |
Heap에서 관리되는 객체는 일정한 Scope가 존재하지 않기 때문에 자동으로 소멸자가 호출되지 않습니다.
따라서 동적 할당된 객체는 명시적으로 delete 또는 delete[]를 호출하여 메모리 누수를 방지합니다.
Human* m = new Human(name);
delete m;
정리 및 복습
소멸자(Destructor)는 객체가 일정한 Scope를 벗어나거나delete또는delete[]되었을 때 호출되는 멤버 함수입니다.- 소멸자의 이름은 클래스 이름과 동일하며
~문자를 prefix로 추가합니다. - 소멸자는
인자및리턴 값을 가질 수 없습니다. Stack메모리에서 관리되는 객체는 Scope를 벗어날 때자동으로 소멸자가 호출됩니다.Heap메모리에서 관리되는 객체는명시적으로 delete 또는 delete[]를 호출해야 합니다.
'C++ > C, C++, STL' 카테고리의 다른 글
디폴트 생성자(Default constructors)와 생성자에서의 delete 키워드 (0) | 2024.02.16 |
---|---|
스마트 포인터(Smart pointer)와 종류 (0) | 2024.02.08 |
클래스(class)와 구조체(struct)의 차이 (0) | 2024.02.08 |
자기 자신을 나타내는 this 포인터 (0) | 2024.02.04 |
얕은 복사(Shallow copy)와 깊은 복사(Deep copy) (0) | 2024.02.04 |