Тема: 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;
}