가상 소멸자는 어떤 경우에 쓰는 건가요?
조회수 12532회
제가 생성자나 다른 함수에 virtual
붙는 건 이해하겠는데
소멸자에 virtual
은 왜 쓰는 건지는 잘 모르겠어요.
객체가 소멸할 땐 상속받은 클래스의 소멸자도 자동으로 불러주잖아요?
근데 virtual
을 써주는 게 무슨 의미가 있죠?
1 답변
-
가상 소멸자는
derived class
인스턴스를 가리키는base class pointer
를delete
할 때 유용하게 쓰입니다.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
의 소멸자가 호출되어 메모리가 정상적으로 해제됩니다.
댓글 입력