探讨C++中一种管理内存的方法

原创 2006年05月31日 22:35:00
C++多么多么强大,对内存的控制细致入微,但优点同时即是缺点,你必须清楚的记得你new出来的每一块内存是怎么释放的。所以C++/CLI才把拖管方式引进来,弥补这个问题。我现在不是要讨论C++/CLI,而是传统C++。
以前在写课程设计FileSolvent时就做过这种尝试,让类自己管理内存,简单的说,对象在觉得自己该释放的时候就释放,到最后都没释放的就统一释放。但这样必须要做到的就是有一个列表保存了这个类每一个实例的指针。这并不难,只有给这个类添加一个静态列表成员,然后在构造函数里把自己加进去,在析构函数里再把自己拿出来就行了:
class SomeClass
...{
  
static vector<SomeClass*> list;
public:
  SomeClass() 
...{ list.push_back(this); }
  
~SomeClass() ...{ list.remove(this); } 
}
;
 
vector
<SomeClass*> SomeClass::list; //VC中静态成员变量需要这样初始化一下
 
只要再给这个list写一个getter,就可以从外面访问这个类型现存的所有实例了。
但如果要让多个类带有这种功能,难道给每个类都添加这段代码吗?这显然不是个好想法。一种思路是使用继承,在基类中写好这些逻辑,子类是你想要的类,但很不幸的,所有子类会共享基类的静态成员,也就是只会有一个list,所有的实例指针都会放进去,那时RTTI会烦死人的。
难道就没有更好的办法了吗?当然会有,我从ATL中受到启发,只要把基类做成模板类,以子类名作为模板参数,只要是不同的子类,就会自己编译出不同的基类,也就会有不同的静态成员,哈,这正是我想要的。
下面的代码写出来和ATL感觉好像啊:

template<class T>  //以子类为模板参数
class ISelfMemMgr
...{
private:
 
static std::vector<T*> instanceList; //这就是容纳所有实例指针的静态列表
protected:
 ISelfMemMgr(
void
 
...{
  T
* pThis = static_cast<T*>(this);  //必须转换为子类指针,要不然是加不进去的
  instanceList.push_back(pThis);
 }

 
virtual ~ISelfMemMgr(void)
 
...{
  T
* pThis = static_cast<T*>(this);
  instanceList.remove(pThis);
 }

}
;
 
这样一来,子类真的只要继承这个基类就够了。但问题还没完,前面所说的目标是要释放的时候尽管释放,没释放的到最后一起释放,怎么实现这个最后一起释放呢?在OnDestroy()里释放吗?当然不好,一方面需要多写代码,忘写了就完了;另一方面这样只对MFC程序有效,我希望这个程序的可复用性更强。其实,不就是想要在程序即将结束时知道一下吗,这种情况C++早就为我们提供了最佳的处理方式:对于全局变量和类静态成员,都会在程序即将结束时被自动析构的,只要在这个析构函数里写点什么就达到目的了。
为此,再添加一个Helper类,目的就是程序结果时释放内存。而且,为了和前述类能够配套使用,这里也使用模板类的形式:
 

template
<class T>
class SelfMemMgrHelper
...{
public:
 
~SelfMemMgrHelper()
 
...{
  ISelfMemMgr
<T>::FinalDelete(); //就是这里要释放全部变量,它会被自动调用
 }

private:
 SelfMemMgrHelper() 
//构造函数声明为私有,防止从外面生成实例
 ...{} 
}
;
然后,再把这两个类互设友元,并且在前面类里面再加一个Helper类的静态成员。并且,为了防止使用时过于麻烦,免去使用者手写静态成员初使化的过程,可以把它封装成一个宏(越来越像ATL):
 
#define DECLARE_SELFMEMMGR_HEAD(type) std::vector< type* > ISelfMemMgr< type >::instanceList;
 SelfMemMgrHelper
< type > ISelfMemMgr< type >::helper;

现在使用时只需要这样:
class SomeClass: public ISelfMemMgr<SomeClass>
...{
...
}
;
 
DECLARE_SELFMEMMGR_HEAD(SomeClass)
 
就这么简单,不再需要其他的辅助内容了。
当然,现在算不上完美,例如还没有考虑上并发控制问题,这就是以后的事了。
附完整的代码如下:
 

#pragma once
#include 
<vector>
template
<class T>
class SelfMemMgrHelper;
template
<class T>
class ISelfMemMgr
...{
 friend 
class SelfMemMgrHelper<T>;
public:
 
static std::vector<T*>& GetInstances() ...return instanceList; }
private:
 
static std::vector<T*> instanceList;
 
static SelfMemMgrHelper<T> helper;
protected:
 ISelfMemMgr(
void
 
...{
  T
* pThis = static_cast<T*>(this);
  instanceList.push_back(pThis);
 }

 
virtual ~ISelfMemMgr(void)
 
...{
  T
* pThis = static_cast<T*>(this);
  
for(std::vector<T*>::iterator it = instanceList.begin(); it != instanceList.end(); it++)
  
...{
   
if(*it == pThis)
   
...{
    instanceList.erase(it);
    
break;
   }

  }

 }

private:
 
static void FinalDelete()
 
...{
  
while(!instanceList.empty())
  
...{
   delete 
*instanceList.begin();
  }

 }

}
;
template
<class T>
class SelfMemMgrHelper
...{
 friend 
class ISelfMemMgr<T>;
public:
 
~SelfMemMgrHelper()
 
...{
  ISelfMemMgr
<T>::FinalDelete();
 }

private:
 SelfMemMgrHelper()
 
...{} 
}
;
#define DECLARE_SELFMEMMGR_HEAD(type) std::vector< type* > ISelfMemMgr< type >::instanceList;
 SelfMemMgrHelper
< type > ISelfMemMgr< type >::helper;

c++的map,set内存结构

1)Set是一种关联容器,它用于存储数据,并且能从一个数据集合中取出数据。它的每个元素的值必须唯一,而且系统会根据该值来自动将数据排序。每个元素的值不能直接被改变。【重点】内部结构采用红黑树的平衡二叉...
  • rosenor1
  • rosenor1
  • 2016年08月20日 21:16
  • 1436

【C++进阶】从内存管理、内存泄漏、内存回收探讨C++内存管理

原文地址:http://www.cr173.com/html/18898_all.html 文章很棒,忍不住转载了 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获...
  • fu_zk
  • fu_zk
  • 2013年10月25日 15:04
  • 3466

C/C++内存管理与Java内存的各种分配

最近在看一些面试题,于是就查找了java与C/C++在内存上的差异 Java的内存管理实质上就是JVM的内存管理   JVM的内存分为两部分:stack和heap   Stack...
  • Losteng
  • Losteng
  • 2016年03月10日 23:03
  • 1196

C++程序设计内存管理器(内存池)

一、New/malloc内存分配很慢 C语言中的标准库函数malloc、free、calloc和realloc,以及C++中的new、new[]、delete和delete[] 操作符,是这两种语...
  • Robin__Chou
  • Robin__Chou
  • 2016年03月26日 20:45
  • 2068

C/C++内存管理之内存池

C++内存管理一直是我比较困惑的问题。俗话说初生牛犊不怕虎,做点啥都new一个,然后delete一个。根本不知道底层会有怎么样的运行机制,慢慢地学习才知道以前学习中有一些东西是不可能在工业中应用的。所...
  • bateerBATEER
  • bateerBATEER
  • 2017年03月28日 21:38
  • 225

《C++高效编程:内存与性能优化》第九章:高效内存管理

  • ywcpig
  • ywcpig
  • 2016年09月14日 21:05
  • 676

java 对象的内存分配和回收

对象优先在Eden上分配 大多数情况下,对象优先在新生代Eden区域中分配。当Eden内存区域没有足够的空间进行分配时,虚拟机将触发一次 Minor GC(新生代GC)。Minor GC期间...
  • u011130752
  • u011130752
  • 2016年03月14日 16:57
  • 395

C++内存分配和管理

[导语] 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中...
  • Jeson_Mei
  • Jeson_Mei
  • 2016年08月16日 11:05
  • 2421

一个C++的内存池和内存管理的实现(一)

用C++编写高效稳定的软件,有效的内存管理通常是绕不开的一个题目,尤其是对于复杂庞大的商业软件。...
  • qiyao_2000
  • qiyao_2000
  • 2015年04月17日 18:11
  • 974

C++内存管理学习笔记(5)

/****************************************************************/ /*            学习是合作和分享式的! /* ...
  • wdzxl198
  • wdzxl198
  • 2013年06月17日 14:31
  • 7474
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:探讨C++中一种管理内存的方法
举报原因:
原因补充:

(最多只允许输入30个字)