//垃圾回收设想
//回收策略,内存整理和多线程问题暂不考虑

//必要的限制:
//1、所有具备垃圾回收功能的类都必须派生自gcBase
//2、只能通过gcPtr和gcSPtr来访问gcBase(和派生类),
// 也就是说,直接申明gcBase的全局变量和通过原生指针gcBase *都不是合法的
// 使用gcBase的全局变量会导致在垃圾回收代码delete一个无效的内存
// 通过原生指针gcBase *访问gcBase会导致垃圾回收提前删除这个对象
//3、gcPtr和gcSPtr原则上都必须知道是哪个gcBase拥有它。
// gcSPtr的拥有者设置成一个全局的gcBase的实例,因此,gcSPtr应该在全局变量和栈变量上使用
//这些限制类似于C++/CLI (vs2005)的垃圾回收
//--------------------------------------------------------------------------------------------------

#pragma warning(disable : 4355)

//垃圾回收策略
struct gcTactic
 ...{
virtual ~gcTactic();
virtual void Check() = 0;

static gcTactic * sm_pInstance;
static void CheckGarbage()
 ...{
sm_pInstance->Check();
}
};

struct gcBase;

//GC指针基类
struct __gc_Ptr__
 ...{
friend gcBase;
private:
gcBase * __gc_m_pParent;
__gc_Ptr__ * __gc_m_pNext;
__gc_Ptr__ * __gc_m_pPrev;

void __InitLink(gcBase * pParent);
static void * operator new (size_t);
static void operator delete (void *);
static void operator delete (void *,size_t);
protected:
gcBase * __gc_m_pRef;
public:
~__gc_Ptr__();

__gc_Ptr__(gcBase * pParent)
 ...{
__gc_m_pRef = 0;
__InitLink(pParent);
}
__gc_Ptr__(gcBase * pParent,gcBase * __r)
 ...{
__gc_m_pRef = __r;
__InitLink(pParent);
}
__gc_Ptr__(gcBase * pParent,const __gc_Ptr__ & __r)
 ...{
__gc_m_pRef = __r.__gc_m_pRef;
__InitLink(pParent);
}
__gc_Ptr__ & operator = (gcBase * __r)
 ...{
__gc_m_pRef = __r;
return *this;
}
__gc_Ptr__ & operator = (const __gc_Ptr__ & __r)
 ...{
__gc_m_pRef = __r.__gc_m_pRef;
return *this;
}
};

//所有具备垃圾回收功能的类都必须派生自此类
struct gcBase
 ...{
friend __gc_Ptr__;
private:
static volatile long __gc_sm_nObjectCounter;
static size_t __gc_sm_nScanCounter;
static gcBase __gc_sm_Root;
static gcBase * __gc_sm_pFirst;
static void __gc_Mark(gcBase * obj);

size_t __gc_m_nScanCounter;
__gc_Ptr__ * __gc_m_pFirstPtr;
gcBase * __gc_m_pNext;
gcBase * __gc_m_pPrev;

public:
static void GarbageCallback();

gcBase();
virtual ~gcBase();
};

//当作成员变量的GC指针
template<class _Ty>
struct gcPtr : public __gc_Ptr__
 ...{
typedef _Ty * _Pty;
typedef gcPtr<_Ty> this_type;

gcPtr(gcBase * pParent)
:__gc_Ptr__(pParent)
 ...{
}
gcPtr(gcBase * pParent,_Pty __r)
:__gc_Ptr__(pParent,__r)
 ...{
}
gcPtr(gcBase * pParent,const this_type & __r)
:__gc_Ptr__(pParent,__r)
 ...{
}

this_type & operator = (_Pty __r)
 ...{
__gc_m_pRef = __r;
if(__gc_m_pRef == NULL)
gcTactic::CheckGarbage();
return *this;
}
this_type & operator = (const this_type & __r)
 ...{
__gc_m_pRef = __r.__gc_m_pRef;
if(__gc_m_pRef == NULL)
gcTactic::CheckGarbage();
return *this;
}
 operator _Pty () const...{
return (_Pty)__gc_m_pRef;
}
 _Pty operator -> () const...{
return (_Pty)__gc_m_pRef;
}
 _Pty * operator & ()...{
return (_Pty *)&__gc_m_pRef;
}
 const _Pty * operator & () const...{
return (const _Pty *)&__gc_m_pRef;
}
};

//在栈上使用的GC指针
template<class _Ty>
struct gcSPtr : public gcPtr<_Ty>
 ...{
typedef gcPtr<_Ty> base_type;
typedef gcSPtr<_Ty> this_type;

gcSPtr()
:gcPtr<_Ty>(NULL)
 ...{
}
gcSPtr(_Pty __r)
:gcPtr(NULL,__r)
 ...{
}
gcSPtr(const base_type & __r)
:gcPtr(NULL,__r)
 ...{
}
gcSPtr(const this_type & __r)
:gcPtr(NULL,__r)
 ...{
}
~gcSPtr()
 ...{
if(__gc_m_pRef != NULL)
 ...{
__gc_m_pRef = NULL;
gcTactic::CheckGarbage();
}
}
this_type & operator = (_Pty __r)
 ...{
base_type::operator = (__r);
return *this;
}
this_type & operator = (const base_type & __r)
 ...{
base_type::operator = (__r);
return *this;
}
};

//--------------------------------------------------------------------------------------------------
//另外一种设想————还没有想好

struct __gcHeap__
 ...{
static __gcHeap__ sm_Heap;
};

#define gc_new new(__gcHeap__::sm_Heap)
 #include "gcbase.h"
#include <windows.h>

#ifndef NULL
#define NULL 0
#endif

struct gcDefaultTactic : public gcTactic
 ...{
volatile long m_bChecking;
gcDefaultTactic()
 ...{
m_bChecking = 0;
}
virtual ~gcDefaultTactic()
 ...{
}
virtual void Check()
 ...{
if(m_bChecking)
return ;
InterlockedExchange(&m_bChecking,1);
gcBase::GarbageCallback();
InterlockedExchange(&m_bChecking,0);
}
};

gcTactic::~gcTactic()
 ...{

}

gcTactic * gcTactic::sm_pInstance = NULL;


volatile long gcBase::__gc_sm_nObjectCounter = 0;
size_t gcBase::__gc_sm_nScanCounter = 1;
gcBase gcBase::__gc_sm_Root;
gcBase *gcBase::__gc_sm_pFirst = NULL;

void __gc_Ptr__::__InitLink(gcBase * pParent)
 ...{
if(pParent == NULL)
pParent = &gcBase::__gc_sm_Root;
__gc_m_pParent = pParent;

__gc_m_pNext = __gc_m_pParent->__gc_m_pFirstPtr;
__gc_m_pPrev = NULL;
if(__gc_m_pNext != NULL)
__gc_m_pNext->__gc_m_pPrev = this;
__gc_m_pParent->__gc_m_pFirstPtr = this;
}

__gc_Ptr__::~__gc_Ptr__()
 ...{
if(this == __gc_m_pParent->__gc_m_pFirstPtr)
__gc_m_pParent->__gc_m_pFirstPtr = __gc_m_pNext;
if(__gc_m_pNext)
__gc_m_pNext->__gc_m_pPrev = __gc_m_pPrev;
if(__gc_m_pPrev)
__gc_m_pPrev->__gc_m_pNext = __gc_m_pNext;
}

struct __gcFinalGarbageCallback
 ...{
~__gcFinalGarbageCallback()
 ...{
gcBase::GarbageCallback();
}
};

gcBase::gcBase()
 ...{
static __gcFinalGarbageCallback __final_gc;
static gcDefaultTactic __celue;
if(gcDefaultTactic::sm_pInstance == NULL)
gcDefaultTactic::sm_pInstance = &__celue;

__gc_m_nScanCounter = 0;
__gc_m_pFirstPtr = NULL;

__gc_m_pNext = __gc_sm_pFirst;
__gc_m_pPrev = NULL;
if(__gc_m_pNext != NULL)
__gc_m_pNext->__gc_m_pPrev = this;
__gc_sm_pFirst = this;

InterlockedIncrement(&__gc_sm_nObjectCounter);
}

gcBase::~gcBase()
 ...{
if(this == __gc_sm_pFirst)
__gc_sm_pFirst = __gc_m_pNext;
if(__gc_m_pNext)
__gc_m_pNext->__gc_m_pPrev = __gc_m_pPrev;
if(__gc_m_pPrev)
__gc_m_pPrev->__gc_m_pNext = __gc_m_pNext;
__gc_m_pFirstPtr = NULL;

InterlockedDecrement(&__gc_sm_nObjectCounter);

gcTactic::CheckGarbage();
}

void gcBase::__gc_Mark(gcBase * obj)
 ...{
obj->__gc_m_nScanCounter = __gc_sm_nScanCounter;

for(__gc_Ptr__ * p = obj->__gc_m_pFirstPtr; p;)
 ...{
obj = p->__gc_m_pRef;
p = p->__gc_m_pNext;

if(obj == NULL)
continue;
__gc_Mark(obj);
}
}

void gcBase::GarbageCallback()
 ...{
++__gc_sm_nScanCounter;
__gc_Mark(&__gc_sm_Root);

for(gcBase * p = __gc_sm_pFirst; p; )
 ...{
gcBase * temp = p->__gc_m_pNext;
if(p->__gc_m_nScanCounter != __gc_sm_nScanCounter)
delete p;
p = temp;
}
}

//--------------------------------------------------------------------------------------------------

__gcHeap__ __gcHeap__::sm_Heap;
 // testgc.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "gcbase.h"

struct BTree : public gcBase
 ...{
gcPtr<BTree> m_pLeft;
gcPtr<BTree> m_pRight;
int m_nID;

BTree(int id)
:m_pLeft(this)
,m_pRight(this)
 ...{
 |