呼び出し例。
hoge.h
#pragma once
struct Hoge
{
int _data1;
unsigned char _data2[1];
};
main.cc
#include "uniqueptr1.h"
#include "uniqueptr2.h"
#include "uniqueptr3.h"
int main()
{
auto p1 = CreateHoge1(100);
auto p2 = CreateHoge2(100);
auto p3 = CreateHoge3(100);
return 0;
}
カスタムデリーターに関数オブジェクトを使用する場合
関数freeを呼び出すためだけにclass(またはstruct)が必要なため冗長。
uniqueptr1.h
#pragma once
#include <memory>
#include "hoge.h"
class MyCustomDeleter
{
public:
void operator()(void* p) const;
};
std::unique_ptr<Hoge, MyCustomDeleter> CreateHoge1(int dataSize);
uniqueptr1.cc
#include "uniqueptr1.h"
#include <stdlib.h>
std::unique_ptr<Hoge, MyCustomDeleter> CreateHoge1(int dataSize)
{
auto hoge = static_cast<Hoge*>(malloc(sizeof(Hoge) - 1 + dataSize));
return std::unique_ptr<Hoge, MyCustomDeleter>(hoge, MyCustomDeleter());
}
void MyCustomDeleter::operator()(void* p) const
{
free(p);
}
カスタムデリーターにstd::functionを使用する場合
std::functionで関数オブジェクトより簡潔に書けた。
uniqueptr2.h
#pragma once
#include <functional>
#include <memory>
#include "hoge.h"
std::unique_ptr<Hoge, std::function<void(Hoge*)>> CreateHoge2(int dataSize);
uniqueptr2.cc
#include "uniqueptr2.h"
#include <stdlib.h>
std::unique_ptr<Hoge, std::function<void(Hoge*)>> CreateHoge2(int dataSize)
{
auto hoge = static_cast<Hoge*>(malloc(sizeof(Hoge) - 1 + dataSize));
return std::unique_ptr<Hoge, std::function<void(Hoge*)>>(hoge, &free);
}
カスタムデリーターに関数ポインターを使用する場合
std::functionを関数ポインターで書き直してみた。
uniqueptr3.h
#pragma once
#include <memory>
#include "hoge.h"
std::unique_ptr<Hoge, void (*)(void* p)> CreateHoge3(int dataSize);
uniqueptr3.cc
#include "uniqueptr3.h"
#include <stdlib.h>
std::unique_ptr<Hoge, void (*)(void* p)> CreateHoge3(int dataSize)
{
auto hoge = static_cast<Hoge*>(malloc(sizeof(Hoge) - 1 + dataSize));
return std::unique_ptr<Hoge, void (*)(void* p)>(hoge, &free);
}