가상 소멸자는 기본 클래스에서 virtual 키워드로 선언된 소멸자입니다. 이것은 기본 클래스에 대한 포인터를 통해 객체를 삭제할 때 파생 클래스의 소멸자가 호출되도록 보장합니다.
class Base { public: virtual ~Base() { /* ... */ } }; class Derived : public Base { public: ~Derived() override { /* ... */ } }; Base* ptr = new Derived(); delete ptr; // 두 소멸자가 모두 호출됩니다.
가상 소멸자가 없다면 잘못된 동작이 발생할 수 있습니다. 파생 클래스의 소멸자가 호출되지 않아 자원이 유출됩니다!
기본 클래스에 가상 함수가 하나도 없다면 소멸자를 가상으로 선언해야 할까요?
답변: 예, 기본 타입 포인터로 삭제할 의도가 있는 경우 상속에서 클래스가 사용될 것으로 예상된다면 필요합니다. 다른 가상 함수가 없더라도 후손의 정확한 삭제를 위해 소멸자를 가상으로 만드는 것이 필요합니다.
class Shape { public: virtual ~Shape() {} };
이야기 1
대규모 그래픽 라이브러리 프로젝트에서 기본 클래스 포인터를 통해 객체를 삭제할 때 OpenGL 자원(버퍼, 텍스처)이 유출되었습니다. 해당 해제는 파생 클래스의 소멸자에 있었지만, 호출되지 않았습니다.
이야기 2
TCP 프로토콜을 위한 네트워크 라이브러리에서 세션을 삭제할 때, 공통 기본 인터페이스를 통해 관리되는 상속 클래스의 소멸자가 호출되지 않았습니다. 이는 많은 소켓이 멈추고 설명자의 한계가 소진되는 결과를 초래했습니다.
이야기 3
C++에서 잘못 선언된(비가상) 기본 클래스의 소멸자가 임베디드 시스템에서 입력/출력 컨트롤러의 시스템 자원 메모리 유출을 초래했습니다. 장치는 드라이버 업데이트 주기를 여러 번 수행한 후 오작동했습니다.