Skip to content

Latest commit

 

History

History
46 lines (42 loc) · 2.78 KB

Item7.md

File metadata and controls

46 lines (42 loc) · 2.78 KB

항목 7. 다형성을 가진 기본클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자

시간 기록 클래스

class TimeKeeper{
public:
    TimeKeeper();
    ~TimeKeeper();    
}

class AtomicClock: public TimeKeeper { ... };
class WaterClock: public TimeKeeper { ... };
class WristClock: public TimeKeeper { ... };
  • 클래스의 혜택을 받는 사용자들은 시간 계산이 어떻게 되는지는 관심이 없고 시간 정보에 접근하고 싶어한다.
    • 객체에 대한 포인터를 얻기위해 팩토리 함수를 만들어 놓는다.
TimeKeeper *getTimeKeeper();
  • 반환되는 객체는 에 있게 되므로 메모리 및 기타 자원의 누수를 막기 위해 객체를 삭제해야 한다.
  • 객체 삭제를 사용자에게 전가하는 것은 에러 발생에 노출될 소지가 있다.
  • 팩토리 함수의 인터페이스를 수정하면 사용자 에러를 방지할 수 있다.
  • 포인터를 통해 날아오는 서브 클래스 객체(AtomicClock, WaterClock, WristClock)는 기본 클래스 포인터(TimeKeeper)를 삭제할때 기본클래스 객체의 소멸자만 호출되고 서브클래스 객체의 소멸자는 실행되지 않는다. (부분 소멸)
  • 부분소멸이 일어났으니 자원의 누수가 발생하게 된다.

자원 누수 해결책

  • 기본 클래스의 소멸자에 virtual키워드를 붙여줌으로써 해결할 수 있다.
  • virtual키워드를 붙여주면 서브 클래스까지 모두 소멸자가 호출된다.
  • 가상 함수를 하나라도 가진 클래스는 가상 소멸자를 가져야 하는게 대부분 맞다.
  • 객체가 가상 소멸자를 가지고 있지 않다면 기본 클래스로 사용되지 않을것이다라고 생각해도 된다.
  • 가상 소멸자를 선언하는 것은 그 클래스에 가상 함수가 하나라도 들어 있는 경우로 한정하는것이 좋다.
  • STL 컨테이너 타입(vector, list, set, unordered_map등)은 가상 소멸자가 없다.
    • STL을 기본 클래스로 잡는 실수를 해서는 안된다.

순수 가상 소멸자

  • 경우에 따라서 순수 가상 소멸자를 두면 편리하게 사용할 수 있다.
  • 클래스가 추상 클래스(인스턴스를 못 만드는 클래스)였으면 좋겠는데 넣을 만한 순수 가상 함수가 없을때가 있다.
  • 순수 가상 소멸자를 선언하는것을 통해 해당 클래스를 추상 클래스로 만들면된다.
  • 단, 순수 가상 소멸자의 정의를 하여야만 한다.
class AWOV{
public:
    virtual ~AWOV() = 0; // 순수 가상 소멸자를 선언
}

AWOV::~AWOV() {} // 순수 가상 소멸자의 정의