센로그
[EC++] 7. 다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자 본문
Effective/Effective C++
[EC++] 7. 다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자
seeyoun 2024. 11. 16. 21:44다형성을 가진 기본 클래스에서 비가상 소멸자를 사용한다면?
- 파생 클래스를 삭제할 때, 파생 클래스의 소멸자는 호출되지 않는다.
- 즉, 기본 클래스의 포인터로 파생 클래스를 가리키는 경우, 기본 클래스의 소멸자만 호출되므로 파생 클래스 부분은 소멸하지 않고 남아있다.
- 따라서, 다형성을 가진 기본 클래스에는 반드시 가상 소멸자를 선언해야 한다.
- 즉, 어떤 클래스가 가상 함수를 하나라도 갖고 있다면, 이 클래스의 소멸자도 가상 소멸자여야 한다.
가상 함수의 동작
- 클래스에 가상 함수가 하나라도 있는 경우, 해당 클래스에 별도의 자료구조가 하나 더 들어가게 된다.
- 클래스의 vtbl(가상 함수 테이블)을 가리키는 vptr(가상 함수 테이블 포인터)이 추가된다.
- 어떤 객체에 대해 어떤 가상 함수가 호출되려고 하면, 호출되는 실제 함수는 그 객체의 vptr이 가리키는 vtbl에 의해 결정되는 것이다. (vtbl에 있는 적절한 함수 포인터와 연결된다)
기본 클래스로 설계되지 않았거나, 다형성을 갖도록 설계되지 않은 클래스의 경우 가상 소멸자를 선언하면 안된다.
- 가상 함수나 가상 소멸자가 추가되는 경우, 객체마다 vptr이 생기기 때문에 객체의 크기가 커져버린다.
- 때문에, 모든 소멸자를 전부 가상으로 선언하는 것 또한 절대 안된다.
어떤 클래스를 기본 클래스로 사용하려고 할 때는 해당 클래스가 기본 클래스로 설계되었는지 확인해야 한다.
- 예를들어 stl 컨테이너 타입은 다형성을 사용하도록 설계된 클래스가 아니다.
- 당연히 소멸자도 비가상 소멸자다.
- 따라서 생각없이 기본 클래스로 사용하려고 한다면 미정의 동작이 발생할 것.
'Effective > Effective C++' 카테고리의 다른 글
[EC++] 9. 객체 생성 및 소멸 과정 중에는 절대로 가상 함수를 호출하지 말자 (0) | 2024.11.17 |
---|---|
[EC++] 8. 예외가 소멸자를 떠나지 못하도록 붙들어 놓자 (0) | 2024.11.16 |
[EC++] 6. 컴파일러가 만들어낸 함수가 필요 없으면 확실히 이들의 사용을 금해 버리자 (3) | 2024.11.13 |
[EC++] 5. C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자 (2) | 2024.11.13 |
[EC++] 4. 객체를 사용하기 전에 반드시 그 객체를 초기화하자 (0) | 2024.11.13 |