Хранение переменных-членов в интеллектуальных указателях и важность явно определенного деструктора - PullRequest
0 голосов
/ 24 мая 2019

У меня есть код, который был написан с использованием старого стиля c ++, например, необработанные указатели, как показано ниже (код 1):

class Thing { 
    private:
        int data;
        Thing* one;
        Thing* second;
        Thing* previous;
    public:
        Thing():one(0), second(0), previous(0) {}
        // Here is my point of focus
        ~Thing() {
            delete one;
            delete second;
            delete previous;
        }
};

class Container {
    private:
        Thing* thing_ptr;
    public:
        Container() : thing_ptr(new Thing()) {}
        void make_empty {
        /*
            Some algorithm for manually destroying the whole structure.
        */
        }
        ~Container() {
            delete thing_ptr;
        }
};

Моя цель - использовать умные указатели вместо необработанных указателей и сделать что-то вроде этого (код 2):

class Thing { 
    private:
        int data;
        std::shared_ptr<Thing> one;
        std::shared_ptr<Thing> second;
        std::shared_ptr<Thing> previous;
    public:
        Thing() : one(nullptr), 
                  second(nullptr), 
                  previous(nullptr) {}

        // Here is my point of focus
        ~Thing() {
        // Do some stuff
        }
};

class Container {
    private:
        std::shared_ptr<Thing> thing_ptr;
    public:
        Container(): thing_ptr(nullptr) {}
        void make_empty {
        /*
            Some recursive algorithm for manually destroying the whole structure.
        */
        }
        /* Some other functions */
        ~Container() {
            // Do some stuff
        }
};

Случай 1. Как компилятор может удалить указатели, которые содержатся в общих указателях, если я не предоставлю соответствующие деструкторы? И будет ли процедура удаления содержать какой-либо вызов деструктора из моих классов?

Случай 2. Если не существует явно определенных деструкторов, и есть некоторая другая переменная-член shared_ptr, которая содержит объект класса Field в классе Thing, например:

class Field {...}

class Thing { 
    private:
        int data;
        std::shared_ptr<Field> field;
        std::shared_ptr<Thing> one;
        std::shared_ptr<Thing> second;
        std::shared_ptr<Thing> previous;
    public:
        Thing() : field(nullptr)
                  one(nullptr), 
                  second(nullptr), 
                  previous(nullptr) {}

        // Here is my point of focus
        ~Thing() {
            // Do some stuff
        }
};

Будет ли вызван деструктор Поля? Если нет, то как компилятор решает, как правильно удалить материал? Есть ли недостатки?

1 Ответ

1 голос
/ 24 мая 2019

Деструкторы переменных-членов автоматически вызываются после содержимого вашего деструктора. Конструкторы вызываются в обратном порядке построения.

Кроме того, вы должны использовать unique_ptr, а не shared_ptr. shared_ptr выполняет подсчет ссылок, который вам почти наверняка не нужен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...