2012-12-22 44 views
1

任務:shared_ptr與T =緩衝區,其中緩衝區具有動態字節量(uint8_t []在最後);allocate_shared與附加的字節緩衝區

是否allocate_shared保證此訂單將被保留: [shared_ptr的數據] [對象] [附加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

你的想法是什麼? –

+0

我的想法?我想單個分配緩衝區,它正在工作,但也許會停止,如果20個字節的allocate_shared頭將被移動到對象之後(不像之前,像現在一樣)在下一個實現中。 –

+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函數,則需要捕獲異常,釋放內存並重新拋出。

我也會考慮將構造函數設爲private,所以buffer對象只能由create函數創建。

0

在端我決定使用:

  • 升壓:: intrusive_ptr與T =緩衝器
  • 升壓::原子與T =標準::的size_t引用計數(未一部分獨立庫)

便攜式單一分配。