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

本文介绍了一个改进版的UniquePtr模板类,用于解决多继承层次中unique_ptr使用不当导致的问题,并通过示例展示了如何正确地使用它来管理不同类型的对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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("");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值