C++ 内存管理器
一个C++内存管理器,可以自动删除任何未使用的堆对象。
引言
我想到一个很酷的项目来尝试。结果就是这个C++内存管理器。它的目的是自动删除应用程序不再使用的堆对象。无需手动删除它们。更好的是 - 它会在不再需要时立即删除它们。你不需要等待指定的时间来删除对象,它也不会占用大量的处理器时间来跟踪和删除所有对象。这是一个简单但非常实用的类。好了,这是类的代码
#pragma once
#pragma warning ( disable: 4312 )
template<typename T> class CMemoryManager
{
private:
template<typename T> class Pointer
{
friend class CMemoryManager;
T* p;
DWORD* pdwRefCount;
public:
template<typename Type> void operator = (Type value)
{
*p = value;
}
template<typename Type> bool operator == (Type value)
{
return (*p == value);
}
operator T* () { return p; }
};
Pointer<T> p;
public:
CMemoryManager()
{
Init();
}
CMemoryManager(T* pNew)
{
Init();
SetNewPointer(pNew);
}
CMemoryManager(int val)
{
Init();
SetNewPointer((T*)val);
}
CMemoryManager(const CMemoryManager& rmm)
{
Init();
UpdateMemoryManager(rmm);
}
~CMemoryManager()
{
if (p.pdwRefCount == NULL) return;
if (*p.pdwRefCount == 0 || --(*p.pdwRefCount) == 0)
{
delete p.p;
delete p.pdwRefCount;
Init();
}
}
void Init()
{
p.pdwRefCount = NULL;
p.p = NULL;
}
void AssignNewPointer(const T* pNew)
{
p.p = (T*)pNew;
}
void CheckRefCount()
{
if (p.pdwRefCount == NULL) NewRefCounter();
}
void SetRefCount(DWORD dwNewCount)
{
CheckRefCount();
*p.pdwRefCount = dwNewCount;
}
void IncreaseRefCount()
{
CheckRefCount();
(*p.pdwRefCount)++;
}
void NewRefCounter()
{
p.pdwRefCount = new DWORD;
*p.pdwRefCount = 0;
}
void SetNewPointer(const T* pNew)
{
Delete();
AssignNewPointer(pNew);
IncreaseRefCount();
}
void Delete()
{
this->~CMemoryManager();
Init();
}
void UpdateMemoryManager(const CMemoryManager& rmm)
{
Delete();
AssignNewPointer(rmm.p.p);
p.pdwRefCount = rmm.p.pdwRefCount;
IncreaseRefCount();
}
void operator = (int val)
{
SetNewPointer((T*)val);
}
void operator = (const T* pmm)
{
SetNewPointer(pmm);
}
void operator = (const CMemoryManager* pmm)
{
UpdateMemoryManager(*prmm);
}
void operator = (const CMemoryManager& rmm)
{
UpdateMemoryManager((CMemoryManager&)rmm);
}
void SetNewAddr(T* pNewAddr, DWORD dwRefCount)
{
Delete();
SetNewPointer(pNewAddr);
SetRefCount(dwRefCount);
}
void Detach()
{
if (*p.pdwRefCount == 1)
{
delete p.pdwRefCount;
delete p.p;
}
p.pdwRefCount = NULL;
p.p = NULL;
}
int GetSize() { return sizeof(*p.p); }
Pointer<T>& operator * () { return p; }
T* operator -> () { return p.p; }
operator T* () { return p.p; }
operator void* () { return p.p; }
void operator delete(void* p) { }
// Do nothing if attempting to delete the object.
// Object will automatically be deleted by the class.
T* GetPointer() { return p.p; }
bool operator == (int nCompare) { return (p.p == (T*)nCompare); }
operator bool () { return (p.p != NULL); }
};
#pragma warning ( default: 4312 )
#define pp CMemoryManager
你所要做的就是将所有堆内存封装在 CMemoryManager
类中。然后,你可以像它们没有被封装一样使用这些指针。或者,至少你应该这样做。试一试!看看它是如何工作的,并报告任何不工作的情况。我不知道 Visual Studio 2003 或更早版本中的 IntelliSense 是否能够真正检测到实际指针的类成员,但在 2005 版本中,它可以完美地工作。所以,再次强调,试一试,告诉我你的想法和它的工作情况。再也不用担心需要手动删除的指针了!另外请注意,不要对它们使用 "delete
"。相反,如果你想释放指针,请调用成员方法 Delete
。如果对象不再使用(引用计数为 0),则它将被释放。另外请记住始终使用容器。如果你将一个普通的指针分配给内存管理器,它将不会保持引用计数!所以,如果可能的话,始终分配实际的内存管理器对象。最后,不要使用这个类来封装你没有责任释放的内存指针。只在自己的内存上使用它。而且,我建议你只在自己分配的新对象上使用它。
我已经更新了这个类。它现在更有效率,也更好。据我所知,没有错误。