ライブラリからこれらのプレーンな C 関数を取得しました。
struct SAlloc;
SAlloc *new_salloc();
void free_salloc(SAlloc *s);
これを C++ でスマート ポインター (std::unique_ptr)、または RAII ラッパーにラップする方法はありますか?
私は主に、独自のラッパー/クラスを作成せずに標準ライブラリの可能性に興味があります。
ライブラリからこれらのプレーンな C 関数を取得しました。
struct SAlloc;
SAlloc *new_salloc();
void free_salloc(SAlloc *s);
これを C++ でスマート ポインター (std::unique_ptr)、または RAII ラッパーにラップする方法はありますか?
私は主に、独自のラッパー/クラスを作成せずに標準ライブラリの可能性に興味があります。
はい、これには 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>;
私はR.MartinhoFernandesの答えが好きですが、これはより短い(しかし効率の悪い)代替案です:
auto my_alloc = std::shared_ptr<SAlloc>(new_salloc(), free_salloc);
別のバリエーション:
#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
。
これを 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
) はコンパイルされません。実装をサポートするには、代わりの削除ファンクターを実装する必要があります。