C++에서는 순수 가상 소멸자(pure virtual destructor)를 선언하는 것이 가능합니다. 다만 한 가지 중요한 규칙이 있습니다. 클래스에 순수 가상 소멸자가 포함되어 있다면, 반드시 해당 소멸자에 대한 함수 본체(function body)를 별도로 정의해 주어야 합니다.
이것이 필요한 이유는 간단합니다. 파생 클래스의 객체가 소멸될 때, 기반 클래스의 소멸자도 반드시 호출되기 때문입니다. 순수 가상으로 선언된 소멸자라 하더라도 객체 소멸 과정에서 실행되어야 하므로 구현부가 존재해야 합니다.
예제 코드
#include <iostream>
using namespace std;
class B {
public:
virtual ~B()=0; // 순수 가상 소멸자
};
B::~B() {
std::cout << "Pure virtual destructor is called";
}
class D : public B {
public:
~D() {
cout << "~D() is executed"<<endl;
}
};
int main() {
B *bptr=new D();
delete bptr;
return 0;
}실행 결과
~D() is executed Pure virtual destructor is called
코드 설명
위 예제에서 B 클래스의 소멸자는 =0 문법을 사용하여 순수 가상 함수로 선언되었습니다. 그러나 클래스 외부에서 B::~B() 형태로 함수 본체를 정의한 것을 확인할 수 있습니다.
main() 함수에서 D 객체를 생성하고 기반 클래스 포인터인 bptr로 가리킨 뒤 delete로 해제하면, 다음과 같은 순서로 소멸자가 호출됩니다.
- 먼저 파생 클래스
D의 소멸자(~D())가 실행됩니다. - 이후 기반 클래스
B의 소멸자가 호출되며, "Pure virtual destructor is called" 메시지가 출력됩니다.
정리
- C++에서 순수 가상 소멸자의 선언은 허용됩니다.
- 순수 가상 소멸자는 반드시 함수 본체를 제공해야 합니다. 그렇지 않으면 링크 오류(linker error)가 발생할 수 있습니다.
- 소멸자를 순수 가상으로 만들면 해당 클래스가 추상 클래스(abstract class)가 되어 직접 인스턴스화할 수 없습니다.