base class의 소멸자를 virtual 로 선언하지 않았을 때 문제점
class TimeKeeper {
public:
TimeKeeper() {}
~TimeKeeper() {} // 비가상 소멸자
};
class AtomicClock: public TimeKeeper {
public:
AtomicClock() {}
~AtomicClock() { std::cout << "AtomicClock destroyed\\n"; }
};
TimeKeeper* getTimeKeeper() {
return new AtomicClock(); // 실제로는 AtomicClock 객체 생성
}
TimeKeeper* tk = getTimeKeeper(); // TimeKeeper 포인터로 AtomicClock 객체를 받음
delete tk; // TimeKeeper의 소멸자만 호출, AtomicClock의 소멸자는 호출되지 않음!
TimeKeeper 같은 기반 클래스가 있고, 이를 상속받은 파생 클래스들(예: AtomicClock, WaterClock, WristWatch)이 있다.getTimeKeeper()는 base class 포인터 (TimeKeeper*)를 반환하지만, 실제로는 파생 클래스 객체를 생성해서 반환함.TimeKeeper 클래스의 소멸자가 virtual로 선언되지 않았기 때문에, delete 연산은 base 클래스의 소멸자만 호출한다.해결 방법
TimeKeeper 클래스의 소멸자를 virtual로 선언하면, base class pointer로 객체를 삭제하더라도 파생 클래스의 소멸자까지 올바르게 호출됨.class Point { // 2D 좌표를 나타냄
public:
Point(int xCoord, int yCoord);
~Point();
private:
int x, y;
};
vptr은 vtbl (가상 테이블) 이라고 불리는 함수 포인터 배열을 가리킨다.vptr 이추가되므로, 객체의 크기는 32 비트 아키텍처에서 96비트, 64 비트 아키텍처에서 128비트로 증가