플로렌스라는 개발자

C++ 가상 파괴자(virtual destructor)의 필요성

프로그래밍/C++ 2019.10.18 댓글 0 Plorence

목차

    일반적으로 파괴자에서 처리해야 할 작업이 없으면 파괴자 정의 자체를 안 하는 경우가 많습니다.

    할당한 걸 해제해줘야 하는 경우 파괴자를 정의하고 처리해줘야 하는 게 정상입니다.

    가상 파괴자는 다음과 같은 상황일때 필요합니다.

    • 기초, 파생 클래스에서 파괴자를 정의 한경우에 (필요로 할 때)

    • 업 캐스팅될 여지가 있는 경우에

     

    가상 파괴자가 아닐 때

    #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;
    }
    파생 파괴자
    기초 파괴자
    기초 파괴자

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

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

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

    그래서 per는 기초 파괴자만 호출되고

    per1는 기초 파괴자, 파생 파괴자 둘 다 호출이 됩니다.

    이때 기초 파괴자까지 호출되는 이유는, 파생 클래스가 소멸될 때 자연스레 기초 클래스의 객체도 사라지니 기초 파괴자가 호출이 됩니다.

     

    결론은 메모리 누수 방지입니다.

    댓글

    0