template <typename Tp>
class AutoCleanHelperBase
{
public:
AutoCleanHelperBase(Tp* ptr)
:m_ptr(ptr)
{ }
virtual void destroy()
{}
protected:
Tp* m_ptr;
};
template <typename Tp, typename Deleter>
class AutoCleanHelper;
template <typename Tp>
class AutoCleanHelper<Tp, void> : public AutoCleanHelperBase<Tp>
{
public:
AutoCleanHelper(Tp* ptr)
:AutoCleanHelperBase<Tp>(ptr)
{ }
void destroy()
{
delete this->m_ptr;
}
};
template <typename Tp, typename Deleter>
class AutoCleanHelper: public AutoCleanHelperBase<Tp>
{
public:
AutoCleanHelper(Tp* ptr, Deleter del)
:AutoCleanHelperBase<Tp>(ptr)
,m_del(del)
{ }
void destroy()
{
(this->m_ptr->*m_del)();
}
private:
Deleter m_del;
};
template <typename Tp>
class AutoClean
{
public:
template <typename Tp1>
AutoClean(Tp1* ptr)
:m_helper(new AutoCleanHelper<Tp1, void>(ptr))
{}
template <typename Tp1, typename Deleter>
AutoClean(Tp1* ptr, Deleter deleter)
:m_helper(new AutoCleanHelper<Tp1, Deleter>(ptr, deleter))
{}
~AutoClean()
{
m_helper->destroy();
delete m_helper;
}
private:
AutoCleanHelperBase<Tp>* m_helper;
};
class CanDestroy
{
public:
~ CanDestroy()
{
std::cout <<"I'm destroy now !!!\n";
}
};
class ExplicitDestroy
{
public:
void destroy()
{
std::cout <<"I'm also destroy now !!!\n";
}
};
int main()
{
AutoClean<CanDestroy> clean1(new CanDestroy);
AutoClean<ExplicitDestroy> clean2(new ExplicitDestroy, &ExplicitDestroy::destroy);
return 0;
}