C++

C++ 가상 소멸자(Virtual Destructor) 총정리

김구티2 2024. 4. 8. 20:43

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 기능이 있을 때마다 즉시 가상 소멸자를 추가해야 한다. 이렇게 하면 나중에 문제가 생길 일은 줄어든다고 할 수 있다.

728x90