본문 바로가기

C/C++/C/C++일반

가상소멸자 사용

C++ 문법을 배울때 함수 앞에 virtual 키워드가 들어가면 가상 함수가 된다고 배웠다.

 

배우고 난 뒤 시간이 지나면 다 까먹기 마련 그래서 이렇게 겨우 생각날 때 정리해 놓는 거다.~~

 

가상함수는 의 특징은 대략 다음과 같다.




즉 가상함수로 선언되면 부모 클래스의 포인터로 해당 가상함수를 호출하더라도 호출은 가장 자식 클래스의 가상함수가 호출 된다.  보다 자세한 내용은 인터넷 검색으로 확인 할 수 있다.

 

이제 가상 소멸자의 사용에 대해 알아보자

다음의 코드는 메모리 누수를 발생시킨다. 어느부분에서 발생되는지 한번 생각해 보자.


▼ 선언부분



▼ 호출부분



▼ 실행 후 메모리 누수


별 이상 없어보인다면 보통 개발자 ~

 

아~ CString 이라 딱 찝으면 센스 있는 개발자 ~

 

소멸자구만 하면 이글을 읽을 필요가 없는 개발자 ~

 

원인은 간단하다. 소멸자가 가상 소멸자가 아니기 때문이다.

 

그럼 왜 위의 사항에서 소멸자가 가상 소멸자가 아니면 안되는 것인가?

 

문제는 delete 부분에서 컴파일러는 부모 포인터로 동적할당된 CBase 영역만 소멸자가 호출 된다는 것이다.

 

아래는 위 코드의 소멸자 호출 상태를 보여준다.


부모 클래스의 포인터 변수는 삭제될 때 부모 클래스의 소멸자만 호출 함으로 자식 클래스의 소멸자는 호출되지 않기 때문에 자식 클래스 멤버변수 str2의 소멸자(CString::~CString())도 호출되지 않는다. CString은 동적할당을 이용해 문자열을 저장 함으로 str2에 저장된 "bbb"의 메모리가 해제되지 않아서 메모리 누스를 일으키는 것이다.

 

위 문제를 해결하기 위해선 가상 소멸자를 명시해줘야한다.


▼ 가상 소멸자 명시