在《C++ Primer》的第18章有如下代码
template<class T> void *CacheObj<T>::operator new(size_t sz) { if (sz != sizeof(T) ) throw std::runtime_error("wrong size"); if (!freestore) { //本句仅分配了内存,并未构造对象 T * array = alloc_mem.allocate(chunk); for (size_t i=0; i!= chunk;i++) //该函数对尚未构造的对象的成员赋值了 add_to_freelist(&array[i]); } T *p = freestore; freestore = freestore->CacheObj<T>::next; return p; } template<class T> void CacheObj<T>:: add_to_freelist(T *p) { p->CacheObj<T>::next = freestore; freestore = p; }
为什么可以这样做?
要回答为什么还是挺困难的,但是可以从C++的内存布局和C++的内存访问机制上得到解释。
提供一段较容易理解的代码,以体现C++的这两种特点:
BYTE buff[256];
T* pT = (T*)buff; // 将 LPBYTE 强制转换为 T*.
这里假设 sizeof(T) <= 256,即使 T 的大小超过了256,这段代码也能正确运行。
这段代码不是对尚未构造的对象的成员赋值,是重写了operator new,在operator new里简单的实现了内存池。chunk是内存池的总大小,每块的大小和T的大小对应,CacheObj这个模板类,第一次new的时候会建立内存池,以后每次只是从内存池链表里取个块作为对象的new分配的内存。
参考这个:
http://www.cnblogs.com/luxiaoxun/archive/2012/08/11/2633423.html