Я пишу код для интеллектуальных указателей в качестве упражнения. Используя онлайн-учебники (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;
}
};
ИЗМЕНИТЬ:
Для этого мне нужен указатель на исходный тип.
Я разместил здесь вопрос: удалить с помощью указателя на Derived, а не на 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. Мне нужно сохранить это. Как я могу это сделать?
SP
конструктор шаблонаSP<T>::SP(U *u) { ... }
и каким-то образом сохранить исходный типU
(который должен быть производным отT
), чтобы иметь возможность вызывать деструкторU
позже. - person Angew is no longer proud of SO   schedule 08.04.2013std::unique_ptr
не соответствует: ideone.com/iyanmY - person Chad   schedule 08.04.2013shared_ptr
должен (и делает) — но AFAIR даже тогда, только когда вы не инициализируете его с помощьюmake_shared
. - person Konrad Rudolph   schedule 08.04.2013SmartPtr<Base> = SmartPtr<Derived>
работать. - person Yakk - Adam Nevraumont   schedule 08.04.2013delete
, напечатанное на исходномU*
. - person Angew is no longer proud of SO   schedule 09.04.2013