가상함수를 사용하지 않는다면..

여러 파생클래스를 가지는 CTimekeeper라는 기본 클래스가 있다고 가정해보자.

이 클래스에 getTimeKeeper라는 팩토리함수( 새로 생성된 파생 클래스 객체에 대한 기본 클래스 포인터 반환 함수 ) 을 만들었다면,

   CTimeKeeper* ptk = getTimeKeeper();     // CTimeKeeper클래스 계통으로부터 동적으로 할당된 객체를 얻는다.

위와 같이 사용을 한뒤 삭제를 해야한다.

   delete ptk;

하지만 위와 같이 삭제를 할 경우 문제가 발생한다.

   1. getTimeKeeper함수가 반환하는 포인터가 파생 클래스객체에 대한 포인터이다.

  2. 이 포인터가 가르키는 객체가 삭제될 때는 기본 클래스 포인터를 통해 삭제된다.

  3. 결정적으로 기본 클래스에 들어있는 소멸자가 비가상 소멸자이다.( 기본 클래스( CTimeKeeper )의 소멸자가 비가상 소멸자라는 가정 하에 )

위와 같은 상황에선 파생클래스(상속받은)의 멤버들은 삭제되지 않고 소멸자도 실행되지 않는다. 

 

해결방법

가상 소멸자를 사용하면 된다.간단하다..

   ps. 가상 함수를 가진 클래스를 보면 거의 가상 소멸자를 사용해야한다.

 

가상함수 남발로 인한 문제점

클래스에 별도의 자료구조( 가상 함수 테이블 )이 들어가게 된다.

   ps. 가상 함수 테이블 : 가상 함수 테이블 포인터 배열 ( 프로그램 실행 중 주어진 객체에 대해 어떤 가상 함수를 호출해야 하는지 판단하는 정보 )

그로 인해 C 등의 다른 언어로 선언된 동일한 자료구조와 호환성이 없어지고 객체 자체의 크기도 커지게 된다.

   ps. 클래스에 가상 함수가 하나라도 들어 있는 경우에만 가상 소멸자를 사용한다.

 

 가상 소멸자가 없는 것들에 주의하자

 STL 컨테이너 타입 전부 ( vector, list, set 등 ), string클래스 등

이러한 것들을 상속하여 사용하지 않도록 주의 하도록 한다.

 

순수(pure)가상 소멸자

경우에 따라 순수 가상 소멸자를 두면 편리하게 사용할 수 있다.

   ps. 추상 클래스( 그 자체로는 자신 타입의 객체를 생성할 수 없는 )로 만들려고 하지만 마땅히 넣을 순수 가상 함수가 없을 경우 순수 가상 소멸자를 만든 다.

   class AWOV

   {

 public :

virtual ~AWOV() = 0;

   };

   주의점 : 반드시 순수 가상 소멸자의 정의를 해 두어야 한다.

 

 

 

* 다형성을 가진 기본 클래스에는 반드시 가상 소멸자를 선언해야 한다. 즉 어떤 클래스가 가상 함수를 하나라도 갖고 있으면, 이 클래스의 소멸자도가상 소멸자이어야 한다. 

* 기본 클래스로 설계되지 않았거나 다형성을 갖도록 설계되지 않은 클래스에는 가상 소멸자를 선언하지 말아야 한다. 

'Programing > etc' 카테고리의 다른 글

킹스툴즈 2008 ( 비주얼스튜디오 문서화 )  (0) 2012.06.12
obb  (0) 2012.05.22
xml 장점 단점  (0) 2012.05.21
순수, 가상함수 차이 활용  (0) 2012.05.21
STL Map  (0) 2012.05.21
Posted by 부우산사나이
: