C++ 문법을 배울때 함수 앞에 virtual 키워드가 들어가면 가상 함수가 된다고 배웠다.
배우고 난 뒤 시간이 지나면 다 까먹기 마련 그래서 이렇게 겨우 생각날 때 정리해 놓는 거다.~~
가상함수는 의 특징은 대략 다음과 같다.
즉 가상함수로 선언되면 부모 클래스의 포인터로 해당 가상함수를 호출하더라도 호출은 가장 자식 클래스의 가상함수가 호출 된다. 보다 자세한 내용은 인터넷 검색으로 확인 할 수 있다.
이제 가상 소멸자의 사용에 대해 알아보자
다음의 코드는 메모리 누수를 발생시킨다. 어느부분에서 발생되는지 한번 생각해 보자.
▼ 선언부분
▼ 호출부분
▼ 실행 후 메모리 누수
별 이상 없어보인다면 보통 개발자 ~
아~ CString 이라 딱 찝으면 센스 있는 개발자 ~
소멸자구만 하면 이글을 읽을 필요가 없는 개발자 ~
원인은 간단하다. 소멸자가 가상 소멸자가 아니기 때문이다.
그럼 왜 위의 사항에서 소멸자가 가상 소멸자가 아니면 안되는 것인가?
문제는 delete 부분에서 컴파일러는 부모 포인터로 동적할당된 CBase 영역만 소멸자가 호출 된다는 것이다.
아래는 위 코드의 소멸자 호출 상태를 보여준다.
부모 클래스의 포인터 변수는 삭제될 때 부모 클래스의 소멸자만 호출 함으로 자식 클래스의 소멸자는 호출되지 않기 때문에 자식 클래스 멤버변수 str2의 소멸자(CString::~CString())도 호출되지 않는다. CString은 동적할당을 이용해 문자열을 저장 함으로 str2에 저장된 "bbb"의 메모리가 해제되지 않아서 메모리 누스를 일으키는 것이다.
위 문제를 해결하기 위해선 가상 소멸자를 명시해줘야한다.
▼ 가상 소멸자 명시
'C/C++ > C/C++일반' 카테고리의 다른 글
2차원 배열 매개변수 전달 방법 (0) | 2015.10.30 |
---|---|
파일 포인터 / feof() 함수 사용 tip (0) | 2015.10.30 |
함수 템플릿, 클래스 템플릿 을 사용하는 상황과 이유 (0) | 2015.10.30 |
함수 포인터 (0) | 2015.10.30 |
재귀함수와 비재귀 함수 성능비교 코드 (0) | 2014.10.09 |