1

この API で raw メモリを管理する小さなクラスが必要です

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バイト数を保持する )。デリーターとして何を使用しますか? または、それをすべて達成するためのより良い方法はありますか?

4

1 に答える 1

2

クラスのユーザーがアロケータを型引数として指定できるようにするため、割り当てと解放の両方でこの引数を参照する必要があります。このため、引数として渡されたアロケーター メソッドを使用する必要があるため、@Kerrek によって作成されたコマンド (関数へのポインターのトリッキーで適切な使用法ではありますが) は無効です。

unique_ptr を使用するとうまくいきます。正しくコメントしたように、独自のデリータを提供する必要があります。上記の私のコメントによると、テンプレートに引数として渡されたアロケータ クラスに基づいている必要があります。

補足: テンプレート宣言に構文エラーがあることに注意してください。正しい構文については、以下のサンプル コードを参照してください (つまり、キーワード「template」が必要です)。

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); } )
        {
        }
};

注意事項:

  • タイプ引数として A を使用しています (tymplate 引数にはすべて大文字を使用する方が読みやすいと思います)。
  • C++11 ラムダ記法を使用して、deleter ファンクターを unique_ptr のコンストラクターに渡しています。このファンクタにはクロージャ状態 (al への参照とサイズ) があり、削除中に使用されます。クロージャーでは、 this ポインター (m_al にアクセスするために必要) とサイズを入れています - 両方とも値で指定します。
于 2012-09-19T16:54:15.690 に答える