2009. 4. 9. 19:27

_set_purecall_handler

// _set_purecall_handler.cpp
// compile with: /W1
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>

class CDerived;
class CBase
{
public:
   CBase(CDerived *derived): m_pDerived(derived) {};
   ~CBase();
   virtual void function(void) = 0;

   CDerived * m_pDerived;
};

class CDerived : public CBase
{
public:
   CDerived() : CBase(this) {};   // C4355
   virtual void function(void) {};
};

CBase::~CBase()
{
   m_pDerived -> function();
}

void myPurecallHandler(void)
{
   printf("In _purecall_handler.");
   exit(0);
}

int _tmain(int argc, _TCHAR* argv[])
{
   _set_purecall_handler(myPurecallHandler);
   CDerived myDerived;
}
_set_purecall_handler는 순수 가상함수가 호출이 되었을때 호출할 콜백 함수이다.
프로세스가 종료 될 때 콜백함수를 설정하는 atexit()와 비슷한 유사한 형태라고 할수 있다.
오늘 알게 되어서 부끄럽지만, 클래스의 생성자가 완료되기 전까지는 해당 클래스의 인스턴스는 같은 형식이라고
할수 없다고 한다.
위와 같은 꼴 때리는 코드를 작성할 일은 없지만, CDerived 클래스의 생성자가 CBase클래스에게 자신의 인스턴
스(this)를 넘기는데, 이게 유효한 코드라고 볼 수가 없다는 것이다.
언뜻 보면 문제가 없어 보이는 코드지만 CBase의 소멸자가 호출 될 때 에러가 발생한다.

해당 코드의 m_pDerived의 메모리 구조를 보면 위의 그림과 같은 요상한  구조가 만들어진다는 거다.