用C++模板来展示new与delete操作符原理 - 蘭陵N散記

JerryXia 发表于 , 阅读 (0)
第一部分是与malloc功能相同,是从堆上面申请内存块第二部是调用类的构造方法来初始化刚申请的内存。

delete是new的逆过程,先调用类的析构方法来反初始化,再把刚申请的内存还给堆。

new []与delete []是针对数组操作符,要注意是通过new []分配的对象,不能用delete来释放对象,否则会有内存泄漏。当然通过new分配的对象,不能用delete[]来释放对象。后面我会通过代码来说明为什么。

下面是C++ 中的new与delete函数原型,申请内存失败会抛出异常bad_alloc

void* operator new(std::size_t) throw (std::bad_alloc);void* operator new[](std::size_t) throw (std::bad_alloc);void operator delete(void*) throw();void operator delete[](void*) throw();

使用举例:

int* p1 = new int();delete p2;int* p2 = new int[5];delete [] p2;

终于到了用模板来模拟new与delete操作符,代码中有注释说明,其中对于调用类的构造方法,采用一种C++标准中称作in-place construtor的方式。使用原型为T* = new(pbuff) T(),直译的话就是在pbuff这块内存构造T类,而不用再去堆上面申请内存。这种技巧大量应用在对象池的实现中,即pbuff这块内存可以挂在链表中反复地使用(这里先不展开说了)。

/** * A simulation of c++ new T() & new T(param) operation */  struct NewObj{    template <typename T>    inline void operator()(T*& pObj)    {        // allocate memory form heap        void * pBuff = malloc(sizeof(T));        // call constructor        pObj = new (pBuff) T();    }    template <typename T, typename P>    inline void operator()(T*& pObj, const P& param)    {        // allocate memory form heap        void * pBuff = malloc(sizeof(T));        // call constructor, pass one param        pObj = new(pBuff) T(param);    }};  /** * A simulation of c++ delete T operation */  struct DeleteObj  {      template <typename T>      inline void operator()(T*& pObj)      {          if ( NULL == pObj ) { return ;}          // call destructor          pObj->~T();          // free memory to heap          free((void*)pObj);          pObj = NULL;      }  };  /** * A simulation of c++ new T[N]() operation */  struct NewObjArray  {      template <typename T>      inline void operator()(T*& pObj, unsigned int size)      {          // save the number of array elements in the beginning of the space.          long * pBuff = (long *) malloc (sizeof(T) * size + sizeof(long));          *((unsigned int *) pBuff) = size;          pBuff++;          // change pointer to T type, then can use pT++          T * pT = (T *) pBuff;          // save the pointer to the start of the array.          pObj = pT;          // now iterate and construct every object in place.          for (unsigned int i = 0; i < size; i++)          {              new((void *) pT) T();              pT++;