Program Language/C & C++

[C++] 가상 파괴자(Virtual Destructor)의 필요성

야곰야곰+책벌레 2021. 4. 9. 14:07
728x90
반응형

일반적으로 파괴자에서 처리해야 할 작업이 없으면 정의 자체를 안 하는 경우가 많다. 할당을 진행한 경우에는 파괴자를 정의하고 처리를 해줘야 하는게 정상이다.

파괴자가 필요할 때는 아래와 같다.

  - Base, Abstract class에서 파괴자 정의를 한 경우 (필요로 할 때)

  - Upcasting 될 여지가 있는 경우

#include <iostream>
using namespace std;
class Person
{
public:
	~Person()
	{
		cout << "기초 파괴자 \n";
	}
	Person()
	{
	}
};

class Man : public Person
{
public:
	~Man()
	{
		cout << "파생 파괴자 \n";
	}
};

int main(void)
{
	Person * per = new Man();
	Person * per1 = new Person();
	delete per;
	delete per1;
	int a = 0;
}
실행결과
기초파괴자
기초파괴자

호출된 파괴자들이 가상이 아니라면 포인터 형에 해당하는 파괴자만 호출된다.

Man이라는 파생 클래스를 가리켜도 파생 클래스의 파괴자는 호출되지 않는다.

파생 클래스에서 파괴자가 해야 할 작업이 있을 때는 치명적인 문제가 발생한다.

#include <iostream>
using namespace std;
class Person
{
public:
	virtual ~Person()
	{
		cout << "기초 파괴자 \n";
	}
	Person()
	{
	}
};

class Man : public Person
{
public:
	~Man()
	{
		cout << "파생 파괴자 \n";
	}
};

int main(void)
{
	Person * per = new Man();
	Person * per1 = new Person();
	delete per;
	delete per1;
	int a = 0;
}
실행결과
기초파괴자
기초파괴자
기초파괴자

가상 파괴자라면 객체 형에 해당하는 파괴자가 호출됩니다.

포인터 형이 어떤 것이든 가리키고 있는 객체형 파괴자가 호출됩니다.

이렇게 되면 파생 클래스의 파괴자, 기초 클래스의 파괴자가 호출되며 파생 클래스의 파괴자가 먼저 호출됩니다.

 

per1는 기초 파괴자만 호출되고, per은 기초 파괴자, 파생 파괴자 둘 다 호출됩니다.

메모리 누수를 방지하기 위해서는 기초 클래스로 사용되는 모든 클래스는 반드시 virtual destructor로 선언해야 한다.

728x90
반응형