가상 소멸자는 어떤 경우에 쓰는 건가요?


제가 생성자나 다른 함수에 virtual붙는 건 이해하겠는데 소멸자에 virtual은 왜 쓰는 건지는 잘 모르겠어요.

객체가 소멸할 땐 상속받은 클래스의 소멸자도 자동으로 불러주잖아요? 근데 virtual을 써주는 게 무슨 의미가 있죠?

  • 2016년 01월 13일에 작성됨

조회수 326


1 답변


좋아요
0
싫어요
채택취소하기

가상 소멸자는 derived class 인스턴스를 가리키는 base class pointerdelete할 때 유용하게 쓰입니다.

class Base{
public:
    ~Base() {
        cout << "Base destructor!" << endl;
    }
};

class Derived : public Base{
public:
    char* largeBuffer;
    Derived() {
        largeBuffer = new char[3000];
    }

    ~Derived() {
        cout << "Derived destructor!" << endl;
        delete[] largeBuffer;
    }
};

위 코드는 base의 소멸자를 virtual로 설정하지 않았습니다. 이 상황에서 다음의 코드1,2는 같은 일을 할까요?

소스코드

int main(){
    //코드1
    cout << "---Derived* der1 = new Derived()---" << endl;
    Derived* der1 = new Derived();
    delete der1;

    //코드2
    cout << "\n\n---Base* der2 = new Derived()---" << endl;
    Base* der2 = new Derived();
    delete der2;

}

결과)

---Derived* der1 = new Derived()---
Derived destructor!
Base destructor!


---Base* der2 = new Derived()---
Base destructor!

코드1의 경우에는 말씀하신 것처럼 Drived class의 소멸자가 알아서 Base Class의 소멸자를 불러 줍니다. 그래서 buffer가 잘 delete 되었지요.

그런데 코드2의 경우는 Derived destructor가 불리지 않았습니다. buffer가 delete 되지 않고 어딘가에 남아 있겠지요. Base 포인터가 Derived 클래스의 인스턴스를 가리키고 있지만 Derived의 멤버에 접근할 수 없어 이런 결과가 나타난 것입니다

가상 소멸자는 이런 상황에서 메모리가 누수되는걸 막기 위해 씁니다.

class Base{
public:
    virtual ~Base() {
        cout << "Base destructor!" << endl;
    }
};

과 같이 Base 소멸자를 virtual로 설정하면 이젠 코드2의 경우에도 Derived class의 소멸자가 호출되어 메모리가 정상적으로 해제됩니다.

  • 2016년 01월 13일에 작성됨

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close