这也表明,微软开始慢慢疏远CFixedAlloc了,回过头来看MFC6,CFixedAlloc却用在了每个临时句柄映射对象类中,如CWnd和CGdiObject,有以下为证:
class CTempGdiObject : public CGdiObject但这些类从MFC7.1(VC++2003)中就已被移除,也许微软MFC开发小组有其自己的理由吧。
{
DECLARE_DYNCREATE(CTempGdiObject)
DECLARE_FIXED_ALLOC(CTempGdiObject);
};
内存释放
当某个对象被删除,且“释放列表”在同一分配的CPlex中时,CFixedAlloc会返回一个节点到一个“释放列表”中,因为CPlex对象是单向链接的,所以在整个程序生命期都会保持已分配状态(或直到它们的表头被删除)。事实上,CFixedAlloc不仅仅是进行内存分配,它是一个再循环器:按需进行分配但并不释放,为后续的分配请求作保留。
通常,这在频繁地使用new/delete/new/delete情况下,会带来更好的速度提升,但对于短时间内需要大量内存的这种情况,可能会有些问题,这时,程序会一直占有这部分内存,直到CPlex表头被删除,除非用户在使用完内存后,显式地调用CFixedAlloc::FreeAll()来释放这部分内存。也就是说,如果之前已删除所有分配的对象,就可在任意时候调用CFixedAlloc::FreeAll()来自己释放内存,否则,内存会直到CFixedAlloc对象销毁时才会被释放。提示一下:全局对象是在进入WinMain()之前的启动代码中创建的,而在程序退出WinMain()后、自身卸载前才会被销毁。
CFixedAlloc与继承
在与派生类一起使用CFixedAlloc时,还必须多一点了解,比如说以下情况:
class Base如果后面代码中用了Child *p = new Child,将会调用Child::operator new()而不是CFixedAlloc,这时该怎么办呢,请看下面:
{
DECLARE_FIXED_ALLOC(Base);
};
class Child : public Base
{
};
class Base当然了,如果类是抽象类,而我们又把Base类声明为FIXED_ALLOC,这怎么也说不过去,因此,关于在类继承中使用CFixedAlloc,必须知道delete操作符为static但不为virtual,再看以下代码:
{
DECLARE_FIXED_ALLOC(Base);
};
class Child : public Base
{
DECLARE_FIXED_ALLOC(Child);
};
Base *p = new Child;在这种情况中,将会调用Base::operator delete(),这可就麻烦大了。以下是可行的解决方案:
delete p;
class Base
{
public:
virtual void Destroy() {delete this;}
DECLARE_FIXED_ALLOC(Base);
};
class Child : public Base
{
public:
virtual void Destroy() {delete this;}
DECLARE_FIXED_ALLOC(Child);
};
Base *p = new Child;
p->Destroy();