반응형
Effective C++ 항목7
: 다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자.
- 객체에서 메모리 등 자원의 누수를 막기 위해서는 소멸자 호출
class TimeKeeper
{
public:
TimeKeeper();
~TimeKeeper();
...
};
class AtomicClock: public TimeKeeper { ... };
class WaterClock: public TimeKeeper { ... };
class WristClock: public TimeKeeper { ... };
...
// 팩토리 메서드 패턴
TimeKeeper* ptk = getTimeKeeper();
...
delete ptk;
- 문제 발생!
- 기본 클래스의 소멸자가 비가상 소멸자인 경우, 그의 파생 클래스가 삭제될 때 프로그램의 동작이 미정의 사항. (보통은 파생 클래스가 소멸되지 않음)
- 해결책 : 기본 클래스의 소멸자를 가상 소멸자로 만듦
virtual ~TimeKeeper()
- 가상함수를 포함한 클래스는 무조건 가상 함수 테이블 포인터라고 하는 자료구조를 갖게 됨
- 포인터 크기는 아키텍처와 관계 (32비트 환경이라면 포인터 크기는 32비트, 64비트 환경이면 64비트)
- 메모리 비효율을 막기 위해서 가상 함수가 하나라도 있는 클래스에 대해서만 가상 소멸자 선언할 것!
class SpecialString: public std::string { ... }; // STL 은 가상 소멸자가 없음
SpecialString *pss = new SpecialString("Doom");
std::string* ps;
. . .
ps = pss;
. . ..
// 정의되지 않은 동작 발생
// SpecialString 의 소멸자가 호출되지 않아서
// *ps 의 SpecialString 부분에 있는 자원 누출
delete ps;
- 순수 가상 소멸자가 유용하게 쓰이는 다른 예
- 1) 추상 클래스로 만들고 싶은 클래스인데, 어떤 함수를 가상 함수로 두어야할지 모르겠다면?
- => 순수 가상 소멸자 선언!
- 1) 추상 클래스로 만들고 싶은 클래스인데, 어떤 함수를 가상 함수로 두어야할지 모르겠다면?
반응형
'Book & Lecture > Effective C++' 카테고리의 다른 글
Effective C++ 항목9 : 객체 생성 및 소멸 과정 중에는 절대로 가상 함수를 호출하지 말자 (0) | 2023.02.12 |
---|---|
Effective C++ 항목8 : 예외가 소멸자를 떠나지 못하도록 붙들어 놓자 (0) | 2023.02.06 |
Effective C++ 항목6 : 컴파일러가 만들어낸 함수가 필요 없다면 사용을 금지하자 (0) | 2023.01.27 |
Effective C++ 항목5 : 컴파일러가 기본으로 만드는 함수들에 촉각을 세우자 (0) | 2023.01.26 |
Effective C++ 항목4 : 객체를 사용하기 전에 반드시 그 객체를 초기화하자 (0) | 2023.01.25 |