カスタム削除機能でstd::unique_ptr
を使用する場合、未加工の新しいものではなくstd::make_unique
を使用したいと思います。 VC++ 2013を使用しています。カスタムの削除機能を使用している場合、std::unique_ptr
を使用する方法はないと思われます。私は何かを逃したのですか、それとも本当ですか?
追加情報:
開いているCOMポートのWindowsハンドルを保持するためにstd::unique_ptr<HANDLE, custom_deleter>
を使用しています。
このためのカスタムRAIIクラスを作成することはできましたが、それほど難しくはありませんでしたが、std::unique_ptr
を使用することの難しさ、難しさ、悪さを実感していました。
make_unique
の要点は、「new
を使用してT
与えられたコンストラクタ引数からを作成し、delete
を使用して破棄する」という概念をカプセル化することです。
カスタムの削除機能が必要な場合は、createオブジェクトをどのように指定するかを指定する必要があります。その場合、emplacing maker関数を使用することで得られるものはありません。
特定の一意のリソースハンドルのカスタムメーカー関数の例をいくつか書きました この投稿では 。
カスタムのフリー関数を呼び出すカスタムの削除機能を使用して、Cスタイルのメモリ管理をstd::unique_ptr
にラップする方法を次に示します。これには、std::make_unique
[〜#〜] live [〜#〜] に類似したmake関数ヘルパーがあります。
#include <iostream>
#include <functional>
#include <memory>
// Some C style code that has some custom free function ptr...
extern "C" {
struct ABC { };
enum free_type_e {
FREE_ALL,
FREE_SOME
};
typedef void (free_f)(enum free_type_e free_type, void *ptr);
struct some_c_ops { free_f* free_op; };
void MY_free(enum free_type_e free_type, void *ptr)
{
printf("%s:%d ptr=%ld\n", __func__, __LINE__, (long)ptr);
(void)free_type;
free(ptr);
}
}; // extern "C"
template<typename T>
using c_unique_ptr = std::unique_ptr<T,std::function<void(T*)>>;
template <typename T>
c_unique_ptr<T> make_c_unique(some_c_ops* op, free_type_e free_type)
{
return c_unique_ptr<T>(static_cast<T*>(calloc(1, sizeof(T))),
std::bind(op->free_op, free_type, std::placeholders::_1));
}
void foo(c_unique_ptr<ABC> ptr)
{
std::cout << __func__ << ":" << __LINE__
<< " ptr=" << reinterpret_cast<size_t>(ptr.get()) << std::endl;
}
int main()
{
some_c_ops ops = { MY_free };
c_unique_ptr<ABC> ptr = make_c_unique<ABC>(&ops, FREE_ALL);
std::cout << __func__ << ":" << __LINE__
<< " ptr=" << reinterpret_cast<size_t>(ptr.get()) << std::endl;
foo(std::move(ptr));
std::cout << __func__ << ":" << __LINE__
<< " ptr=" << reinterpret_cast<size_t>(ptr.get()) << std::endl;
}
可能な出力:
main:48 ptr=50511440 foo:40 ptr=50511440 MY_free:20 ptr=50511440 main:53 ptr=0