use*_*007 5 c++ std unique-ptr c++11
仅出于教育目的,我正在编写一个小型的智能指针类,此刻不是共享的,只是像C ++ 11中的unique_ptr这样的简单指针。我想要的不是一个完全正常的实现,而只是基础,创建,默认/ custom删除等等。
我一直在尝试查看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;
}
Run Code Online (Sandbox Code Playgroud)
这使用了一种称为类型擦除的东西。虽然有一些 C++ 库可以做到这一点(例如,boost::any),但在这种情况下并不太困难。
假设您有一些自定义删除器:
struct deleter
{
void operator()(void *)
{
cout << "deleting" << endl;
// Do some other stuff.
}
};
Run Code Online (Sandbox Code Playgroud)
但您希望支持具有相同签名的其他人,而不强迫您的用户在自己的代码中使用虚拟函数。
首先定义一个基类:
struct base_deleter_holder
{
virtual void delete_it(void *p) = 0;
};
Run Code Online (Sandbox Code Playgroud)
您的类将保存指向该基类的指针。
现在编写一个依赖于实际删除器类型的派生类:
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);
}
};
Run Code Online (Sandbox Code Playgroud)
您可以添加实用程序函数来帮助您创建该类型的对象:
template<class Deleter>
base_deleter_holder *make_deleter_holder(const Deleter &d)
{
return new deleter_holder<Deleter>(d);
}
Run Code Online (Sandbox Code Playgroud)
现在,当有人使用删除器调用您的模板函数时,您可以创建实际的派生类型,并将其存储在类中的基指针中。使用虚函数,您可以使用基指针来调用派生类的方法:
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);
Run Code Online (Sandbox Code Playgroud)
完整示例:
#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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
414 次 |
| 最近记录: |