我正在爲智能指針編寫代碼作爲練習。在線使用教程(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
但現在,因爲觀看的意見和答案,我認爲兩者都相關。我有構造函數:
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的對象進行存儲。我需要保留該對象。我怎樣才能做到這一點?
如果某個基類沒有虛擬析構函數,並且有人試圖通過指向該基類的指針刪除派生類,那麼某個人做錯了。 – Chad 2013-04-08 18:52:02
爲了達到這個目的,你必須給'SP'一個模板構造函數'SP :: SP(U * u){...}'並以某種方式存儲原始類型'U'(它必須從' T')能夠稍後調用'U'的析構函數。 –
Angew
2013-04-08 18:55:35
C++ 11是否規定一個兼容的智能指針必須這樣做?看起來'std :: unique_ptr'沒有:http://ideone.com/iyanmY – Chad 2013-04-08 18:58:55