解决unique_ptr在不同继承层次转化指针和deleter的问题

来源:互联网 发布:游戏程序员需要做什么 编辑:程序博客网 时间:2024/05/19 18:37

unique_ptr在多继承层次使用时,如果使用不当,容易出现
B* p = new D(); delete p;的问题
因此这里提出一个UniquePtr旨在正确处理析构。当然你需要付出一点小小的性能代价

包含文件

#include <memory>template<typename T>struct DeleteFuncs{ static void deleteFunc(void* obj) { delete (T*)obj; }};struct UniqueDeleter{ void(*m_deleter)(void*) = [](void*){}; UniqueDeleter(void(*func)(void*)) : m_deleter(func){} void operator()(void* ptr){ m_deleter(ptr); }};template<class _Ty, class... _Types> inline typename std::enable_if<!_STD is_array<_Ty>::value, _STD unique_ptr<_Ty, UniqueDeleter> >::type MakeUnique(_Types&&... _Args){ return (_STD unique_ptr<_Ty, UniqueDeleter>(new _Ty(_STD forward<_Types>(_Args)...), DeleteFuncs<_Ty>::deleteFunc));}template<typename T>using UniquePtr = typename std::unique_ptr<T, UniqueDeleter>;

测试代码

struct B{    ~B()    {        printf("~B()\n");    }};struct D : B{    ~D()    {        printf("~D()\n");    }};void deleteB(void* b){    printf("deleteB\n");    delete (B*)b;}void deleteD(void* d){    printf("deleteD\n");    delete (D*)d;}void test(){    puts("");    {        UniquePtr<D> ptrD = MakeUnique<D>();        UniquePtr<B> ptrB = std::move(ptrD);    }    puts("");    {        UniquePtr<B> ptrB{ new D, deleteD };    }    puts("");    {        UniquePtr<B> ptrB{ new B, deleteB };    }    puts("");    {        UniquePtr<B> ptrB{ new D, deleteD };        UniquePtr<D> ptrD = { (D*)ptrB.release(), ptrB.get_deleter() };    }    puts("");    {        UniquePtr<B> ptrB{ new D, deleteD };        UniquePtr<D> ptrD = std::move((UniquePtr<D>&) ptrB);    }    puts("");    {        UniquePtr<B> ptrB{ new D, deleteD };        UniquePtr<D> ptrD = (UniquePtr<D>&&) ptrB;    }    puts("");}
阅读全文
0 0
原创粉丝点击