retainCount 매커니즘을 흉내내보았다.
객체할당시 4바이트를 추가로 할당하여 retainCount 영역으로 사용.
실사용은 해보지 않은 코드이므로 충분한 검증이 필요하다.
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
#define DECLARE_RETAIN(CLASSNAME) \
private: \
static size_t CLASSNAME ## __RETAINEDCLASS_CLASSSIZE__; \
static unsigned int* __fastcall CLASSNAME ## __RETAINEDCLASS_RETAINCOUNTVARABLEPOINTER(void *rawMemory) { \
return (CLASSNAME::CLASSNAME ## __RETAINEDCLASS_CLASSSIZE__ > 0? (unsigned int *)(((char*)rawMemory) + CLASSNAME::CLASSNAME ## __RETAINEDCLASS_CLASSSIZE__): 0); \
} \
unsigned int __fastcall CLASSNAME ## __GET_RETAIN_COUNT__(void) { \
return *CLASSNAME::CLASSNAME ## __RETAINEDCLASS_RETAINCOUNTVARABLEPOINTER(this); \
} \
public: \
static void* operator new(size_t size) { \
return ((CLASSNAME *)malloc((CLASSNAME::CLASSNAME ## __RETAINEDCLASS_CLASSSIZE__ = size) + sizeof(unsigned int)))->retain(); \
} \
static void operator delete(void *rawMemory) { \
unsigned int *retainCount = CLASSNAME::CLASSNAME ## __RETAINEDCLASS_RETAINCOUNTVARABLEPOINTER(rawMemory); \
if (*retainCount > 0 && !(--(*retainCount))) free(rawMemory); \
} \
__property unsigned int retainCount = {read = TRetainedClass__GET_RETAIN_COUNT__}; \
CLASSNAME* __fastcall retain(void) { \
(*CLASSNAME::CLASSNAME ## __RETAINEDCLASS_RETAINCOUNTVARABLEPOINTER(this))++; \
return this; \
}
#define USE_RETAIN(CLASSNAME) size_t CLASSNAME::CLASSNAME ## __RETAINEDCLASS_CLASSSIZE__ = 0;
#define PREVENT_DESTRUCTOR_MULTICALL if (retainCount != 1) return;
class TRetainedClass
{
DECLARE_RETAIN(TRetainedClass);
public:
__fastcall ~TRetainedClass(void)
{ PREVENT_DESTRUCTOR_MULTICALL
ShowMessage("dealloc");
}
};
USE_RETAIN(TRetainedClass);
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
TRetainedClass *test = new TRetainedClass;
ShowMessage(test->retainCount);
test->retain();
ShowMessage(test->retainCount);
delete test;
ShowMessage(test->retainCount);
delete test;
}
//---------------------------------------------------------------------------