【问题标题】:Smart Pointer Custom Deleter智能指针自定义删除器
【发布时间】:2016-05-28 20:47:40
【问题描述】:

仅出于教育目的,我正在编写一个小型智能指针类,目前不是共享的,只是像 C++ 11 中的 unique_ptr 这样的简单类。 我想要的不是一个完整的实现,而只是基础,创造, 默认/自定义删除等。

我一直在尝试查看 Microsoft Visual Studio 中标准的实施,我确实掌握了一般实施,但我被卡住了 使用默认/自定义删除。 所以我的问题是,实现这种功能的最佳技术是什么?

仅出于教育目的可以轻松实现它,还是最终它太复杂且不值得?

干杯

嗨,阿米,

你对这样的事情有什么看法?

template <class _Ty>
    struct default_delete
    {

        constexpr default_delete() = default;

        void operator()(_Ty* Ptr)
        {

        std::cout << "Default Delete" << std::endl;

        }

    };


template <class T, class _Dl=default_delete<T>>
            class Smart_Pointer2_Base;

    template <class T, class _Dl>
    class Smart_Pointer2_Base
    {
        T *ptr;  // Actual pointer
        _Dl _deleter;
    public:
        // Constructor
        explicit Smart_Pointer2_Base(T *p = NULL) { ptr = p; }

        Smart_Pointer2_Base(T* p, _Dl) { prt = p; _deleter = _Dl; }

        // Destructor
        ~Smart_Pointer2_Base() { _deleter(ptr);}

        // Overloading dereferencing operator
        T & operator * () { return *ptr; }


        T * operator -> () { return ptr; }
    };


int main()
{

    struct CloserStruct {
        void operator()(int* toDelete) { std::cout << "Custom Delete"<<std::endl; }
    };
    smtpr::Smart_Pointer2_Base<int, CloserStruct> pi(new int(5));

return 0;
}

【问题讨论】:

  • @Arif_Khan 您刚刚链接了这个问题。也许很快就会有一个有效的答案;)

标签: c++ c++11 std unique-ptr


【解决方案1】:

这使用了一个叫做type erasure的东西。虽然有 C++ 库可以做到这一点(例如,boost::any),但在这种情况下并不太难。

假设您有一些自定义删除器:

struct deleter
{
    void operator()(void *)
    {
        cout << "deleting" << endl;
        // Do some other stuff.
    }
};

但您希望支持具有相同签名的其他人,而不强制您的用户在自己的代码中使用虚函数。

首先定义一个基类:

struct base_deleter_holder
{
    virtual void delete_it(void *p) = 0;
};

你的类将持有一个指向这个基类的指针。

现在编写一个依赖于实际删除器类型的派生类:

template<class Deleter>
struct deleter_holder :
    public base_deleter_holder
{
    Deleter m_d;

    explicit deleter_holder(const Deleter &d) : m_d(d)
    {}
    virtual void delete_it(void *p)
    {
        m_d(p);
    }
};

您可以添加一个实用函数来帮助您创建其类型的对象:

template<class Deleter>
base_deleter_holder *make_deleter_holder(const Deleter &d)
{
    return new deleter_holder<Deleter>(d);
}

现在,当有人使用删除器调用您的模板函数时,您可以创建实际的派生类型,并将其存储在您的类中的基指针中。使用虚函数,你可以使用基指针来调用派生类的方法:

    deleter d;

    // pd should be a member of your pointer class.
    base_deleter_holder *pd = make_deleter_holder(d);

    // Here's how to use it.
    pd->delete_it(nullptr);

完整示例:

#include <functional> 
#include <iostream> 


using namespace std; 


struct base_deleter_holder 
{ 
    virtual void delete_it(void *p) = 0; 
}; 


template<class Deleter> 
struct deleter_holder :  
    public base_deleter_holder 
{ 
    Deleter m_d; 

    explicit deleter_holder(const Deleter &d) : m_d(d) 
    {} 
    virtual void delete_it(void *p) 
    { 
        m_d(p); 
    } 
}; 


struct deleter 
{ 
    void operator()(void *) 
    { 
        cout << "deleting" << endl; 
    } 
}; 


template<class Deleter> 
base_deleter_holder *make_deleter_holder(const Deleter &d) 
{ 
    return new deleter_holder<Deleter>(d); 
} 


int main() 
{ 
    deleter d; 
    base_deleter_holder *pd = make_deleter_holder(d); 
    pd->delete_it(nullptr); 
} 

【讨论】:

  • 我认为没有类型擦除的unique_ptr-like 解决方案要简单得多,尽管类型擦除肯定是一个有用的工具:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-19
  • 1970-01-01
  • 2012-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-03
相关资源
最近更新 更多