Тема: Smart pointers
Намагаюся розібратися з розумними покажчиками.
Для прикладу я створив спрощену структуру даних "Кільцевий список" (принаймні я так надіюсь, бо раніше я не робив цієї структури)
struct slist
містить два поля
data - це корисні дані
next - покажчик що вказує на наступний елемент
class list
це клас за допомогою якого можна управляти цією структурою
містить два поля
shared_ptr<slist> currentEle - поточний елемент
shared_ptr<slist> firstEle - перший елемент
і методи
first (захищений метод) - для встановлення першого елемента лиса
operator >> додати новий елемент
operator << переглянути елемент під номером n
clear - очистити список для нового заповнення
В мене виникли такі питання:
Якщо потрібно примусово звільнити пам'ять, то це робиться методом reset (чи я його не правильно застосовую) ?
Якщо я використовую розумні покажчики то мені в деструкторі нічого не потрібно прописувати ?
Навіщо weak_ptr ? Я бачив приклади, але не можу їх відтворити
Ось таку я інформацію знайшов
"розумний покажчик, який містить "слабке" посилання на об'єкт, керований покажчиком std :: shared_ptr."
...
"Якщо два об'єкти посилаються один на одного «жорстко», очевидно, вони не видаляться, якщо не вжити додаткових дій"
В мене об'єкти посилаються «жорстко» ? Вино ж замкнуті в коло (останній вказує на першого), то правильно в мене відбувається очищення ( коли буде викликана метод clear або буде здійснений вихід за області видимості ) ?
Я не застосовував weak_ptr бо не знаю де його правильно застосувати.
#include <iostream>
#include <memory>
using namespace std;
struct slist
{
int data;
shared_ptr<slist> next;
~slist(){ cout << "\nDelete - slist\n"; }
};
class list
{
public:
list() : currentEle(nullptr) {}
~list() { cout << "\nDelete - list\n"; }
list &operator >> (int d)
{
if (currentEle == nullptr)
{
first(d);
return *this;
}
unique_ptr<slist> t(new slist);
t->data = d;
t->next = firstEle;
currentEle->next = move(t);
currentEle = currentEle->next;
return *this;
}
int operator << (int n)
{
if (firstEle == nullptr)
return -1;
shared_ptr<slist> t(firstEle);
for (int i(0); i < n; i++)
if (t->next != nullptr)
t = t->next;
else
return -1;
return t->data;
}
void clear()
{
if (currentEle == nullptr)
return;
shared_ptr<slist> t;
currentEle = firstEle;
while (currentEle->next != nullptr)
{
t = move( currentEle->next );
currentEle.reset();//delete
currentEle = move(t);
}
currentEle.reset();
firstEle.reset();
}
private:
shared_ptr<slist> currentEle;
shared_ptr<slist> firstEle;
void first(int d)
{
currentEle.reset( new slist );
currentEle->data = d;
currentEle->next = currentEle;
firstEle = currentEle;
}
};
int main(int argc,char *argv[])
{
{
unique_ptr<list> mylist(new list);
*mylist >> 8 >> 7 >> 9;
//демонстрація замкненості кола
cout << (*mylist << 1000) << endl;
}
cout << "\nNEW\n";
{
unique_ptr<list> mylist(new list);
*mylist >> 8 >> 7 >> 9 >> 10 >> 55;
cout << endl << (*mylist << 100) << endl;
//демонстрація очищення
mylist->clear();
cout << endl << (*mylist << 100) << endl;
}
getchar();
return 0;
}