7

ライブラリからこれらのプレーンな C 関数を取得しました。

struct SAlloc;
SAlloc *new_salloc();
void   free_salloc(SAlloc *s);

これを C++ でスマート ポインター (std::unique_ptr)、または RAII ラッパーにラップする方法はありますか?

私は主に、独自のラッパー/クラスを作成せずに標準ライブラリの可能性に興味があります。

4

4 に答える 4

14

はい、これには unique_ptr を再利用できます。カスタムデリータを作成するだけです。

struct salloc_deleter {
    void operator()(SAlloc* s) const {
        free_salloc(s); // what the heck is the return value for?
    }
}

using salloc_ptr = std::unique_ptr<SAlloc, salloc_deleter>;
于 2013-02-11T09:01:47.527 に答える
3

私はR.MartinhoFernandesの答えが好きですが、これはより短い(しかし効率の悪い)代替案です:

auto my_alloc = std::shared_ptr<SAlloc>(new_salloc(), free_salloc);
于 2013-02-11T09:25:11.823 に答える
0

別のバリエーション:

#include <memory>

struct SAlloc {
  int x;
};
SAlloc *new_salloc() { return new SAlloc(); }
void   free_salloc(SAlloc *s) { delete s; }

struct salloc_freer {
  void operator()(SAlloc* s) const { free_salloc(s); }
};
typedef std::unique_ptr<SAlloc, salloc_freer> unique_salloc;
template<typename... Args>
unique_salloc make_salloc(Args&&... args) {
  auto retval = unique_salloc( new_salloc() );
  if(retval) {
    *retval = SAlloc{std::forward<Args>(args)...};
  }
  return retval;
}

int main() {
   unique_salloc u = make_salloc(7);
}

http://sscce.org/にするための本文SAllocとさまざまな関数を含めました。これらの実装は重要ではありません。

のメンバーが表示されている限りSAlloc、上記では、を作成すると同時にイニシャライザリストのようにそれらを作成できます。SAlloc引数を渡さない場合は、全体がゼロになりますSAlloc struct

于 2013-02-11T12:50:32.887 に答える
0

これを C++ でスマート ポインタ ( std::unique_ptr) または RAII ラッパーにラップする方法はありますか?

はい。ここでは、スマート ポインターを正しく初期化するオブジェクトを作成するファクトリ関数が必要です (そして、ポインター インスタンスを常に正しく構築するようにします)。

std::shared_ptr<SAlloc> make_shared_salloc()
{
    return std::shared_ptr<SAlloc>(new_salloc(), free_salloc);
}

// Note: this doesn't work (see comment from @R.MartinhoFernandes below)
std::unique_ptr<SAlloc> make_unique_salloc()
{
    return std::unique_ptr<SAlloc>(new_salloc(), free_salloc);
}

これらの関数を呼び出した結果を (必要に応じて) 他のスマート ポインターに割り当てることができ、ポインターは正しく削除されます。

std::make_shared編集: または、 SAlloc に特化することもできます。

編集 2: 2 番目の関数 ( make_unique_salloc) はコンパイルされません。実装をサポートするには、代わりの削除ファンクターを実装する必要があります。

于 2013-02-11T09:41:59.427 に答える