我努力使自己实现shared_ptr
。我遇到问题make_shared
。的std::make_shared
的主要特征在于它分配计数器块和对象在连续的存储器块。我如何做同样的事情?Make_shared - 自己实现
我试图做这样的事情:
template<class T>
class shared_ptr
{
private:
class _ref_cntr
{
private:
long counter;
public:
_ref_cntr() :
counter(1)
{
}
void inc()
{
++counter;
}
void dec()
{
if (counter == 0)
{
throw std::logic_error("already zero");
}
--counter;
}
long use_count() const
{
return counter;
}
};
template<class _T>
struct _object_and_block
{
_T object;
_ref_cntr cntr_block;
template<class ... Args>
_object_and_block(Args && ...args) :
object(args...)
{
}
};
T* _obj_ptr;
_ref_cntr* _ref_counter;
void _check_delete_ptr()
{
if (_obj_ptr == nullptr)
{
return;
}
_ref_counter->dec();
if (_ref_counter->use_count() == 0)
{
_delete_ptr();
}
_obj_ptr = nullptr;
_ref_counter = nullptr;
}
void _delete_ptr()
{
delete _ref_counter;
delete _obj_ptr;
}
template<class _T, class ... Args>
friend shared_ptr<_T> make_shared(Args && ... args);
public:
shared_ptr() :
_obj_ptr(nullptr),
_ref_counter(nullptr)
{
}
template<class _T>
explicit shared_ptr(_T* ptr)
{
_ref_counter = new counter_block();
_obj_ptr = ptr;
}
template<class _T>
shared_ptr(const shared_ptr<_T> & other)
{
*this = other;
}
template<class _T>
shared_ptr<T> & operator=(const shared_ptr<_T> & other)
{
_obj_ptr = other._obj_ptr;
_ref_counter = other._ref_counter;
_ref_counter->inc();
return *this;
}
~shared_ptr()
{
_check_delete_ptr();
}
};
template<class T, class ... Args>
shared_ptr<T> make_shared(Args && ... args)
{
shared_ptr<T> ptr;
auto tmp_object = new shared_ptr<T>::_object_and_block<T>(args...);
ptr._obj_ptr = &tmp_object->object;
ptr._ref_counter = &tmp_object->cntr_block;
return ptr;
}
但是当我删除对象和计数器块,无效的堆块发生异常。
围绕共享指针管理的两个强制性代码片段是(a)引用计数算法,以及(b)实际的* delete *,这两个选项都不包括在本文中。我们不介意读者。发布展示实际问题的[**完整MCVE **](http://stackoverflow.com/help/mcve)。声明“当我删除对象和计数器块...”表明你正在删除两个从未被直接分配的东西(实际上唯一的直接分配tmp_object永远不会被保留)。 – WhozCraig 2014-12-09 11:39:07
@WhozCraig谢谢!我已更新帖子 – 2014-12-09 12:33:19
您的实施缺少一些关键功能。如果添加它们,解决方案可能会简单地显示在现有代码之外。缺少的东西:删除器的类型擦除,存储与托管对象无关的指针(也许更多,比如线程安全的引用计数,弱引用计数,..)'shared_ptr'是复杂的,并且花费很长时间来开发目前的形式。 – dyp 2014-12-09 12:50:01