任务:shared_ptr,T =缓冲区,缓冲区有动态字节数(末尾为uint8_t []);
allocate_shared是否保证将保留此订单: [shared_ptr data] [object] [附加butebuffer]
因为其他方式不起作用,例如: [对象] [shared_ptr数据] [附加butebuffer]
其他实施想法?
template <class T>
class addon_allocator : public boost::noncopyable
{
public :
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
public :
template<typename U> struct rebind
{
typedef addon_allocator<U> other;
};
public :
explicit addon_allocator( std::size_t size )
:m_size( size )
{
}
~addon_allocator()
{
}
addon_allocator(const addon_allocator<T>& other)
:m_size(other.m_size)
{
}
template <class U>
explicit addon_allocator(const addon_allocator<U>& other)
:m_size(other.get_addon_size())
{
}
pointer address(reference r)
{
return &r;
}
const_pointer address(const_reference r)
{
return &r;
}
pointer allocate(size_type cnt, typename std::allocator<void>::const_pointer = 0)
{
assert( cnt == 1 );
return reinterpret_cast<pointer>(
::operator new(sizeof(T) + m_size)
);
}
void deallocate(pointer p, size_type)
{
::operator delete(p);
}
std::size_t get_addon_size() const
{
return m_size;
}
private:
const std::size_t m_size;
};
class buffer : public boost::noncopyable
{
public:
buffer( std::size_t size )
:m_size(size)
{
}
const std::size_t m_size;
uint8_t m_data[];
static boost::shared_ptr<buffer> create(std::size_t size)
{
boost::allocate_shared<buffer>(
addon_allocator<buffer>(size),
size
);
}
};
答案 0 :(得分:2)
您的代码也可以在libstdc ++中使用std::allocate_shared
的实现,但我认为没有任何保证内存布局会这样。
由于您已经有一个用于创建shared_ptr
的特定函数,因此手动执行内存分配会更加轻松,而不是将allocate_shared
与自定义分配器一起使用:
class buffer : public boost::noncopyable
{
public:
buffer( std::size_t size ) throw()
:m_size(size)
{
}
const std::size_t m_size;
uint8_t m_data[];
static boost::shared_ptr<buffer> create(std::size_t size)
{
void* addr = ::operator new(sizeof(buffer) + size);
return boost::shared_ptr<buffer>(::new(addr) buffer(size));
}
};
这种方式不需要分配器类型,维护的代码更少,代码全部集中在一个地方。这确实失去了allocate_shared
仅进行单个分配(并保持shared_ptr ref计算与对象相邻的元数据)的优势,但它保证可以在任何实现上工作......由此权衡取决于您是值得的。
此代码依赖于buffer
构造函数为无抛出,如果它可以抛出create
函数需要捕获异常,释放内存并重新抛出。
我还会考虑将构造函数设为私有,因此buffer
对象只能由create
函数创建。
答案 1 :(得分:0)
最后我决定使用:
便携式单一分配。