一个类似于Java的GC功能的指针.(二)

ookook 2003-12-12 04:36:58
由于MSDN说不能连续回复超过三次,所以另开一个 :)
//GarbageCollect.h文件(第四部分)


template <typename _C>
bool operator == (const int _X, const _GC_Y<_C>& _T)
{
return _T == _X;
}
template <typename _C>
bool operator != (const int _X, const _GC_Y<_C>& _T)
{
return _T != _X;
}

template <typename _C>
class _GC_Z
{
public:
_GC_Z()
{
m_pBaseClass = NULL;
}
~_GC_Z()
{
delete m_pBaseClass;
}
_GC_Y<_C>& operator()(_C* pBuf)
{
#ifdef _DEBUG
m_pBaseClass = new _GC_Y<_C>(pBuf);
_GC_ASSERT(NULL != m_pBaseClass);
return *m_pBaseClass;
#else
//这个地方在Release版本中内存分配失败时存在问题(不过发生几率很小,约为%0.01)
return *(m_pBaseClass = new _GC_Y<_C>(pBuf));
#endif
}
_GC_Y<_C>& operator [] (unsigned int uiSize)
{
#ifdef _DEBUG
m_pBaseClass = new _GC_Y<_C>(uiSize);
_GC_ASSERT(NULL != m_pBaseClass);
return *m_pBaseClass;
#else
//这个地方在Release版本中内存分配失败时存在问题(不过发生几率很小,约为%0.01)
return *(m_pBaseClass = new _GC_Y<_C>(uiSize));
#endif
}
private:
_GC_Y<_C>* m_pBaseClass;
};

#pragma warning(default: 4284)

#define _GC_NEW
#define GC_NEW _GC_NEW

#define GC_POBJECT(_X) _GC_Y<_X>
#define GC_PBOOL _GC_Y<bool>
#define GC_LPBOOL _GC_Y<bool>
#define GC_PSTR _GC_Y<char>
#define GC_LPSTR _GC_Y<char>
#define GC_PSZ _GC_Y<char>
#define GC_PCHAR _GC_Y<char>
#define GC_PUCHAR _GC_Y<unsigned char>
#define GC_PBYTE _GC_Y<unsigned char>
#define GC_LPBYTE _GC_Y<unsigned char>
#define GC_PSHORT _GC_Y<short>
#define GC_PUSHORT _GC_Y<unsigned short>
#define GC_PWORD _GC_Y <unsigned short>
#define GC_LPWORD _GC_Y<unsigned short>
#define GC_PINT _GC_Y<int>
#define GC_LPINT _GC_Y<int>
#define GC_PUINT _GC_Y<unsigned int>
#define GC_LPUINT _GC_Y<unsigned int>
#define GC_PLONG _GC_Y<long>
#define GC_LPLONG _GC_Y<long>
#define GC_PULONG _GC_Y<unsigned long>
#define GC_PDWORD _GC_Y<unsigned long>
#define GC_LPDWORD _GC_Y<unsigned long>
#define GC_PFLOAT _GC_Y<float>
#define GC_LPVOID _GC_Y<char>

#define GC_OBJECTS(_X) _GC_Z<_X>()
#define GC_OBJECT(_X, _Y) _GC_Z<_X>()(new _X##_Y)
#define GC_BOOL _GC_Z<bool>()
#define GC_STR _GC_Z<char>()
#define GC_CHAR _GC_Z<char>()
#define GC_UCHAR _GC_Z<unsigned char>()
#define GC_BYTE _GC_Z<unsigned char>()
#define GC_SHORT _GC_Z<short>()
#define GC_USHORT _GC_Z<unsigned short>()
#define GC_WORD _GC_Z<unsigned short>()
#define GC_INT _GC_Z<int>()
#define GC_UINT _GC_Z<unsigned int>()
#define GC_LONG _GC_Z<long>()
#define GC_ULONG _GC_Z<unsigned long>()
#define GC_DWORD _GC_Z<unsigned long>()
#define GC_FLOAT _GC_Z<float>()
#define GC_VOID _GC_Z<char>()

#ifdef _UNICODE
#define GC_PTSTR GC_PWORD
#define GC_LPTSTR GC_LPWORD
#define GC_PTCHAR GC_PWORD
#define GC_LPTCHAR GC_LPWORD
#define GC_TCHAR GC_WORD
#else
#define GC_PTSTR GC_PSTR
#define GC_LPTSTR GC_LPSTR
#define GC_PTCHAR GC_PCHAR
#define GC_LPTCHAR GC_PCHAR
#define GC_TCHAR GC_CHAR
#endif

#endif /* end _GARBAGE_COLLECT_H */
...全文
17 7 打赏 收藏 举报
写回复
7 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
Hmilu 2004-03-08
Mark
  • 打赏
  • 举报
回复
whoho 2004-03-08
我没有仔细看程序,据说是采用引用计数
前几天我看了标准库中的auto_ptr,当然这和引用计数不同
后来我上网查了一些资料,知道了一些策略
比如写时复制,转移责任,引用链,引用计数等等
感觉各种技术各有优缺,即使有时候能够处理所有简单类型了
对于复杂类的垃圾收集仍是个问题
真正的垃圾收集机制,我觉得不是简单地用以上这么些代码行
能够解决的,否则也不会成为java的一大卖点

——我就不仔细追踪代码了,如果真如楼上某些大虾所说,
采用引用计数的话,那这个程序还是会出现问题
引用计数无法消除引用环路问题
建议楼主再仔细作一些测试,看看问题会在什么样的情况下出现

当然不管怎样作为探索和学习,我觉得还是有必要的
  • 打赏
  • 举报
回复
oyd 2004-02-04
骗人的,做来做去,把c++的指针作的都不是c++的东西了
c++指针是一个32位数(目前的大部分系统中)
我们本来可以对它进行各种操作:利用它的sizeof,对它进行任意的类型转换,最后还能换回来,还能对它进行位运算,
现在你一下子把他的功能全砍了,还不如去用java呢
  • 打赏
  • 举报
回复
fly3chong 2003-12-23
mark,写得很规范呀,象我这样的新手是要好好学下的了
  • 打赏
  • 举报
回复
ookook 2003-12-12
一个类似于Java的GC功能的指针.(一) 见
http://expert.csdn.net/Expert/topic/2557/2557623.xml?temp=.4174768
(谁在<一>上发个帖子,把<二>链上,我无法回复了。)
  • 打赏
  • 举报
回复
ookook 2003-12-12
由于MSDN说不能连续回复超过三次,所以另开一个 :)
改为CSDN
  • 打赏
  • 举报
回复
ookook 2003-12-12
//GarbageCollect.h文件(完)
//Usage.cpp

/*
* 目的:为了简化C++程序员释放指针的痛苦,特编写了有类似于Java的GC功能的指针.
* 概述:使用GC--GarbageCollect.h--可以自动回收无用的内存,避免内存泄漏.
* 版权:
* 缩写:GC--Garbage Collect
* 用法:GarbageCollect.h提供了对应于基本数据类型的数据类型;GarbageCollect.h
* 也提供了指向基本数据类型的指针类型.使用时要使用GarbageCollect.h提供
* 的数据类型声明指针,为指针分配存贮空间;然后就可以像通常使用普通指针那
* 样使用指针了.这样声明的指针不需要释放存贮空间,也就是不需要delete,系
* 统会在存贮空间不再使用时,自动释放.用户还可以在声明指针时使用自己定
* 义的数据类型(如class CA),这时在为指针分配存储空间是要使用GC_OBJECT或
* GC_OBJECTS(详见下面的例子),这种指针也不需要自己释放存储空间,系统也会
* 在存储空间不再使用时自动释放.同时GC还对内存访问越界进行了检测,在
* Debug版本中如果出现内存访问越界,系统会给出提示框;在Release版本中,如
* 果出现内存访问越界的情况,系统会自动修改指针,使指针指向存储空间的最开
* 始和最末尾(对应于内存访问下溢和上溢).
*
* <类型对照参考表>
* ======================================================================
* 基本数据类型 | GC提供的类型 | GC提供的指向基本类型的指针
* ----------------------------------------------------------------------
* bool | GC_BOOL | GC_PBOOL | GC_LPBOOL
* ----------------------------------------------------------------------
* STR<微软定义> | GC_STR | GC_PSTR | GC_LPSTR
* ----------------------------------------------------------------------
* char | GC_CHAR | GC_PCHAR | GC_PSZ
* ----------------------------------------------------------------------
* unsigned char | GC_UCHAR | GC_PUCHAR |
* ----------------------------------------------------------------------
* BYTE<微软定义> | GC_BYTE | GC_PBYTE | GC_LPBYTE
* ----------------------------------------------------------------------
* short | GC_SHORT | GC_PSHORT |
* ----------------------------------------------------------------------
* unsigned short | GC_USHORT | GC_PUSHORT |
* ----------------------------------------------------------------------
* WORD<微软定义> | GC_USHORT | GC_PWORD | GC_LPWORD
* ----------------------------------------------------------------------
* int | GC_INT | GC_PINT | GC_LPINT
* ----------------------------------------------------------------------
* unsigned int | GC_UINT | GC_PUINT | GC_LPUINT
* ----------------------------------------------------------------------
* long | GC_LONG | GC_PLONG | GC_LPLONG
* ----------------------------------------------------------------------
* unsigned long | GC_ULONG | GC_PULONG |
* ----------------------------------------------------------------------
* DWORD<微软定义>| GC_DWORD | GC_PDWORD | GC_LPDWORD
* ----------------------------------------------------------------------
* float | GC_FLOAT | GC_PFLOAT |
* ----------------------------------------------------------------------
* void | GC_VOID | GC_LPVOID |
* ----------------------------------------------------------------------
* TCHAR<微软定义>| GC_TCHAR | GC_PTCHAR | GC_LPTCHAR
* ----------------------------------------------------------------------
* | | GC_PTSTR | GC_LPSTR
* ----------------------------------------------------------------------
* <自定义类型> | GC_OBJECTS | GC_POBJECT |
* ----------------------------------------------------------------------
* | GC_OBJECT | GC_POBJECT |
* ======================================================================
*
*/



//-----------------------------用法举例-----------------------------------//

//GC并不需要这些头文件,是下面使用的到的其它函数要求这些头文件
#include <assert.h>
#include <iostream.h>

//要是用GC功能,要包含GarbageCollect.h头文件
#include "GarbageCollect.h"

//下面把GC指针完全当作普通指针来用,只是不需要程序员去手工回收内存
GC_PBYTE MemCpy(GC_PBYTE pFrom, GC_PBYTE pTo, unsigned int uiLen)
{
assert(NULL != pFrom);
assert(pTo != NULL);
//GC指针的GetSize()函数可以得到当初指针分配的存储空间的大小
//GC指针的GetCurrent()函数可以得到指针偏移的大小
assert(pFrom.GetSize() - pFrom.GetCurrent() >= uiLen);

GC_PBYTE pTempFrom = pFrom;
GC_PBYTE pTempTo = pTo;

//这个地方之所以时ui<uiLen-1,而不是ui<uiLen,是因为ui=uiLen-1时,如果再执
//行pTempTo++或pTempFrom++就会造成访问非法内存情况.
for (unsigned int ui=0; ui<uiLen-1; ui++)
*pTempTo++ = *pTempFrom++;
*(pTempTo) = *(pTempFrom);
return pTo;
}

GC_PBYTE MemAlloc(unsigned int uiSize)
{
//分配内存时要使用GC_NEW
return GC_NEW GC_BYTE[uiSize];
}

//一个试例类
class CA
{
public:
CA(int i, int j,int k) :m_i(i), m_j(j), m_k(k){}
CA() :m_i(0), m_j(0), m_k(0){}
void Show()
{
cout << "i=" << m_i <<" j=" << m_j <<" k=" << m_k << endl;
}
~CA(){}
private:
int m_i, m_j, m_k;
};

void main()
{
//初始指针都为空
GC_PINT pInt;
assert(pInt == NULL);

GC_PBYTE pBuf = MemAlloc(100);
for (int i=0; i<100; i++)
{
*(pBuf+i) = 'A';
}

//分配内存时要使用GC_NEW
GC_PBYTE pAnotherBuf = GC_NEW GC_BYTE[100];
MemCpy(pBuf, pAnotherBuf, 100);

cout << *(pAnotherBuf+99) << endl;
*(pAnotherBuf+99) = '\0';
cout << pAnotherBuf << endl;

//不用释放指针,就可以使指针指向另外一块内存,不会造成内存泄漏
pAnotherBuf = GC_NEW GC_BYTE[10];
*pAnotherBuf = 'B';
pAnotherBuf+=1;
*pAnotherBuf++ = 'B';
*pAnotherBuf = '\0';
pAnotherBuf-=2;
cout << pAnotherBuf << endl;

//指向用户自定义的类的指针,类的构造函数参数用如下方式传入
GC_POBJECT(CA) pCA = GC_NEW GC_OBJECT(CA, (1, 2, 3));
pCA->Show();

GC_POBJECT(CA) pCABuf = GC_NEW GC_OBJECTS(CA)[100];
pCA = pCABuf+2;
pCA->Show();

pCA = NULL;
}

//---------------------------用法举例结束---------------------------------//


  • 打赏
  • 举报
回复
相关推荐
发帖
C++ 语言
加入

6.1w+

社区成员

C++ 语言相关问题讨论,技术干货分享,前沿动态等
申请成为版主
帖子事件
创建了帖子
2003-12-12 04:36
社区公告
暂无公告