【发布时间】:2013-04-08 18:46:11
【问题描述】:
我正在为智能指针编写代码作为练习。使用在线教程(1,2)我开发了一个普通的带引用计数的智能指针类。问题是我无法弄清楚以下内容:
当智能指针检测到不再存在对某个 特定对象,它必须通过指向该对象的指针删除该对象 原始类型,即使最终智能的模板参数 指针是基本类型。这是为了避免对象切片 非虚拟析构函数。
我怎样才能做到这一点。基本上我的代码如下所示(来自教程)。
template < typename T > class SP
{
private:
T* pData; // pointer
RC* reference; // Reference count
public:
SP() : pData(0), reference(0)
{
// Create a new reference
reference = new RC();
// Increment the reference count
reference->AddRef();
}
SP(T* pValue) : pData(pValue), reference(0)
{
// Create a new reference
reference = new RC();
// Increment the reference count
reference->AddRef();
}
SP(const SP<T>& sp) : pData(sp.pData), reference(sp.reference)
{
// Copy constructor
// Copy the data and reference pointer
// and increment the reference count
reference->AddRef();
}
~SP()
{
// Destructor
// Decrement the reference count
// if reference become zero delete the data
if(reference->Release() == 0)
{
delete pData;
delete reference;
}
}
T& operator* ()
{
return *pData;
}
T* operator-> ()
{
return pData;
}
SP<T>& operator = (const SP<T>& sp)
{
// Assignment operator
if (this != &sp) // Avoid self assignment
{
// Decrement the old reference count
// if reference become zero delete the old data
if(reference->Release() == 0)
{
delete pData;
delete reference;
}
// Copy the data and reference pointer
// and increment the reference count
pData = sp.pData;
reference = sp.reference;
reference->AddRef();
}
return *this;
}
};
编辑:
为了实现这一点,我必须有一个指向原始类型的指针。
我在这里发布了一个问题:delete via a pointer to Derived, not Base
但是现在自从查看 cmets 和答案后,我认为两者都是相关的。我有构造函数:
template <typename T>
template <typename U>
Sptr<T>::Sptr(U* u) : obj(u),ref(NULL) {
//do something
ref = new RC();
ref->AddRef();
}
现在考虑Sptr<Base1> sp(new Derived);,其中Derived 派生自Base1。 Base1 具有受保护的构造函数/析构函数。
这是为 T 类型的对象存储的,但我需要通过 U 类型的对象来存储它。我需要保留它。我该怎么做?
【问题讨论】:
-
如果基类没有虚析构函数,而有人试图通过指向该基类的指针删除派生类,则说明有人做错了。
-
要实现这一点,你必须给
SP一个模板构造函数SP<T>::SP(U *u) { ... }并以某种方式存储原始类型U(必须从T派生)才能稍后调用U的析构函数。 -
C++11 是否规定兼容的智能指针必须这样做?
std::unique_ptr似乎没有:ideone.com/iyanmY -
-
您似乎还缺少让
SmartPtr<Base> = SmartPtr<Derived>工作的复制、移动和赋值运算符。
标签: c++ templates pointers g++ smart-pointers