【发布时间】:2014-12-09 21:50:23
【问题描述】:
我正在尝试自己实现shared_ptr。我对make_shared 有疑问。 std::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,两者都是您选择的 不包含在这篇文章中。我们不是介意读者。发布显示实际问题的complete MCVE。语句“当我删除对象和计数器块时...”表明您正在删除从未 直接 分配的 两个 事物(实际上是唯一的直接分配,@987654326 @, 根本不会保留)。
-
@WhozCraig 谢谢!我已经更新了帖子
-
您的实现缺少一些关键功能。如果添加它们,解决方案可能会简单地出现在现有代码之外。缺少什么:删除器的类型擦除,存储与托管对象无关的指针(可能更多,如线程安全引用计数,弱引用计数,..)
shared_ptr很复杂,开发当前形式。
标签: c++ shared-ptr