好了,所以STL端口似乎支持这种功能,在微软(VS 2008)和GNU执行(STL大约GCC 3.4.1的端口)不要因为他们在分配/解除分配的东西构建函数/ dtors。
这里是我的测试代码,显示如何做到这一点。不要以任何方式警告它的完整实施!
#include <list>
#include <assert.h>
namespace my
{
class memory_pool
{
public:
memory_pool() : m_top(0){};
~memory_pool(){};
void* alloc(int size, int align) { void* p = (void*)&m_pool[m_top]; m_top += size; return p; }
void free (void* p) { assert((p >= m_pool) && (p < &m_pool[m_top])); }
private:
char m_pool[0xFFFF];
int m_top;
};
template<class T>
class dynamic_allocator
{
template<typename U> friend class dynamic_allocator;
public:
typedef T value_type;
typedef size_t size_type;
typedef value_type* pointer;
template <class _Tp1> struct rebind { typedef dynamic_allocator<_Tp1> other; };
dynamic_allocator() : m_pPool(NULL){}
dynamic_allocator(memory_pool* pPool){ m_pPool = pPool; }
dynamic_allocator(const dynamic_allocator<T>& alloc) : m_pPool(alloc.m_pPool){}
template< typename U >
dynamic_allocator(const dynamic_allocator<U>& alloc) : m_pPool(alloc.m_pPool){}
~dynamic_allocator() {}
pointer allocate(size_type count){ return allocate(count, NULL); }
pointer allocate(size_type count, const void*) { assert(m_pPool); return (pointer)m_pPool->alloc(count * sizeof(T), __alignof(T)); }
void deallocate(pointer p, size_type count) { assert(m_pPool); m_pPool->free(p); }
void set(memory_pool* pPool) { m_pPool = pPool; }
private:
memory_pool* m_pPool;
};
template< typename T, typename Al = dynamic_allocator<T> >
class list : public std::list<T, Al>
{
public:
typedef typename std::list<T, Al>::allocator_type allocator_type;
list() : std::list<T, Al>(){};
list(const allocator_type& a) : std::list<T, Al>(a){};
~list(){};
void initialise(memory_pool& pool){ std::list<T, Al>::_M_node.set(&pool); } // or something like this
void terminate(void){ clear(); std::list<T, Al>::_M_node.set(NULL); } // or something like this
};
}; // namespace my
class lemon
{
public:
lemon(){} // must be empty ctor as we don't want to have active mem pool in ctor for users to use
~lemon(){}
void initialise(my::memory_pool& pool){ m_list.initialise(pool); }
void terminate(void) { m_list.terminate(); }
void add(float f) { m_list.push_back(f); }
private:
my::list<float> m_list;
};
int main(void)
{
my::memory_pool poolA;
my::memory_pool poolB;
my::dynamic_allocator<float> aa(&poolA);
my::list<float> a(aa);
my::list<float> fail;
std::list<float>::allocator_type bb;
std::list<float> b(bb);
a.push_back(0.2f);
b.push_back(50.0f);
//fail.push_back(19.0f);
a.clear();
b.clear();
lemon lemons[2];
lemons[0].initialise(poolA);
lemons[1].initialise(poolB);
lemons[0].add(10.0f);
lemons[1].add(20.0f);
lemons[1].add(18.0f);
lemons[0].terminate();
lemons[1].terminate();
scanf("press any key\n");
return 0;
}
是在其构造函数中分配表头节点的Microsoft STL吗?理想的STL实现(读取GNU)在构造空容器时不会使用任何内存分配。 – 2011-02-04 12:55:30
是的,微软和我的GNU端口(大约是gcc 3.4.1)都分配了ctor中的头节点。另一方面,STLPort不支持,所以这支持我的需求,请参阅我的答案,以获得完整的示例源代码。 – user176168 2011-02-05 13:36:48