2012-09-17 32 views
0

原始內存我想有它管理原始內存與此API管理與C++的std ::的unique_ptr

template<class allocator = std::allocator<char> > 
class raw_memory 
{ 
    static_assert(std::is_same<char, typename allocator::value_type>::value, 
       "raw_memory: allocator must deal in char"); 
public: 
    raw_memory() = default; 
    raw_memory(raw_memory&&) = default; 
    raw_memory&operator=(raw_memory&&) = default; 
    explicit raw_memory(size_t, allocator const& = allocator()); 
    ~raw_memory();  // deletes any memory 
    char*get();   // returns pter to (begin of) memory 
    void resize(size_t); // re-allocates if necessary, may delete old data 
    size_t size() const; // returns number of bytes currently hold 

    raw_memory(raw_memory const&) = delete; 
    raw_memory&operator=(raw_memory const&) = delete; 
    raw_memory(raw_memory&) = delete; 
    raw_memory&operator=(raw_memory&) = delete; 
}; 

模板參數allocator允許不同的內存對齊選項有點類。

我正在考慮使用std::unique_ptr<char, Deleter>作爲成員(或基數)(加上保存字節數的size_t)。作爲Deleter使用什麼?還是有更好的方法來實現這一切?

+1

將自定義刪除器作爲raw_memory對象的一部分? –

+3

如果你不需要分配器支持,你可以使用'std :: unique_ptr p(std :: malloc(n),std :: free);'。 –

+1

我想你的意思是'typename allocator :: value_type'? – juanchopanza

回答

2

由於您讓您的類的用戶指定分配器作爲類型參數,因此您必須引用這兩個分配和釋放的參數。基於這個原因,@Kerrek提出的建議(儘管函數指針的使用非常棘手),因爲你確實想使用作爲參數傳遞的分配器方法。

使用unique_ptr可以爲你工作。正如你正確地評論過的,你必須提供你自己的刪除器,並且根據我上面的評論,它必須基於作爲模板存儲庫傳遞的分配器類。

邊注意:請注意您的模板聲明中有語法錯誤。請參閱下面我的示例代碼正確的語法(即你必須有關鍵字「模板」):

template< class A = std::allocator<char> > 
class raw_memory 
{ 
private: 
    A m_al; 
    std::unique_ptr< char, std::function<void(char*)> > m_buffer; 

public: 
    raw_memory(size_t size, const A& al = A()) 
     :m_al(al) 
     ,m_buffer(m_al.allocate(size), [this, size](char* ptr){ m_al.deallocate(ptr,size); }) 
     { 
     } 
}; 

幾點需要注意:

  • 我使用的是作爲類型參數(我發現它更易於使用tymplate參數的所有大寫字母)。
  • 使用C++ 11 lambda表示法,我將deleter functor傳遞給unique_ptr的構造函數。這個仿函數有一個閉包狀態(對al的引用和大小),它將在刪除過程中使用。在閉包中,我把這個指針(需要訪問m_al)和大小 - 兩個值。
+0

'std :: vector'有一個構造函數,它需要一個'const分配器&',也就是說,它不需要按照您的建議採用非常量的'allocator&'。 – Walter

+0

@沃爾特 - 你是對的。我試圖避免擁有一個分配器的成員(這隻有在你沒有調整大小時纔有意義)。我修改了我的答案,所以raw_memory具有自己的分配器(構造爲參數分配器的副本),而現在delete函數的閉包具有'this'指針 – Uri