好的,所以 STL 端口似乎确实支持这种功能,而 Microsoft(VS 2008)和 GNU 实现(stl circa gcc 3.4.1 的端口)不支持,因为它们在 ctors/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;
}