1. 가상 소멸자의 개념
가상 소멸자가 아닌 기본 클래스 유형의 포인터를 사용하여 파생 클래스의 객체를 삭제하면, 정의되지 않은 동작이 발생한다. 이 상황을 수정하려면 기본 클래스를 가상 소멸자로 정의해야 한다. 즉, 객체의 소멸과정에서는 포인터 변수의 자료형에 상관없이 모든 소멸자가 호출되어야 하는데, 그 해결책이 가상 소멸자라는 것이다.
예를 들어, 아래 프로그램은 정의되지 않은 동작을 발생시킨다:
// CPP program without virtual destructor
// causing undefined behavior
#include <iostream>
using namespace std;
class base {
public:
base()
{ cout << "Constructing base\n"; }
~base()
{ cout<< "Destructing base\n"; }
};
class derived: public base {
public:
derived()
{ cout << "Constructing derived\n"; }
~derived()
{ cout << "Destructing derived\n"; }
};
int main()
{
derived *d = new derived();
base *b = d;
delete b;
getchar();
return 0;
}
출력:
Constructing base
Constructing derived
Destructing base
기본 클래스 소멸자를 가상화하면, 파생 클래스의 객체가 올바르게 소멸되는 것을 보장한다. 즉, 기본 클래스와 파생 클래스 소멸자가 모두 호출되는 것이다.
예시:
// A program with virtual destructor
#include <iostream>
using namespace std;
class base {
public:
base()
{ cout << "Constructing base\n"; }
virtual ~base()
{ cout << "Destructing base\n"; }
};
class derived : public base {
public:
derived()
{ cout << "Constructing derived\n"; }
~derived()
{ cout << "Destructing derived\n"; }
};
int main()
{
derived *d = new derived();
base *b = d;
delete b;
getchar();
return 0;
}
출력:
Constructing base
Constructing derived
Destructing derived
Destructing base
클래스에 virtual 기능이 있을 때마다 즉시 가상 소멸자를 추가해야 한다. 이렇게 하면 나중에 문제가 생길 일은 줄어든다고 할 수 있다.
'C++' 카테고리의 다른 글
C++ 가상 복사 생성자(Virtual Copy Constructor) 총정리 (0) | 2024.04.09 |
---|---|
C++ 가상 생성자(Virtual Constructor) 총정리 (0) | 2024.04.08 |
C++ 인라인(Inline) 함수 총정리 (0) | 2024.04.04 |
C++ 재귀(Recursion) 총정리 (1) | 2024.04.03 |
C++ 디폴트 인수(Default Arguments) 총정리 (0) | 2024.04.02 |