Должен ли я уничтожить контейнеры STL в деструкторе моего класса, когда класс обернет и контейнер STL, и указатель? - PullRequest
0 голосов
/ 21 декабря 2018

Я вроде понимаю тот факт, что обернутые контейнеры STL класса будут автоматически уничтожены, когда экземпляр этого класса выйдет из области видимости.Таким образом, мне не нужно писать деструктор, когда класс только упаковывает контейнеры STL.Но что, если класс также должен управлять некоторыми указателями?

Скажем, в некоторых разработках CUDA я хочу, чтобы класс обрабатывал указатель устройства и контейнер STL.

class Image{
    private:
        float *data_device;
        std::array<int, 2> shape;
    public:
        // some constructors and methods
        ~Image(){
            cudaFree(data_device);
            // what to do with the STL array?
        }
};

В приведенном выше случае мне нужен деструктор, чтобы освободить память для data_device.Но я должен иметь дело с массивом STL?Если так, как я могу уничтожить shape правильно?

Ответы [ 3 ]

0 голосов
/ 21 декабря 2018

Вы правы, создавая деструктор, который вручную разрушает все, чем управляет ваш класс.

Однако это не предотвращает разрушение всего остального.Ваши участники будут автоматически уничтожены после , когда деструктор запустится;ваш деструктор дополнительно .

Итак, вы все сделали правильно.

0 голосов
/ 21 декабря 2018

Вы можете себе представить, что закрывающая скобка деструктора дополнительно имеет вызовы деструктора каждого члена (и базы), в обратном порядке построения.

Таким образом, вам не нужно ничего делать для правильно сконструированного члена, которым являются все контейнеры std.Но давайте вернемся немного назад.

Но что, если класс также должен управлять некоторыми указателями?

Вы не должны писать такой класс.Вместо этого вы используете класс, работа которого sole заключается в управлении ровно одним указателем в качестве альтернативы «некоторому указателю».В качестве бонуса вам теперь не нужно беспокоиться о двойном освобождении, потому что Image не имеет конструктора копирования по умолчанию

// cuda Deleter for std::unique_ptr
struct CudaFree
{
    void operator()(float * ptr) { cudaFree(ptr); }
}

class Image{
    private:
        std::unique_ptr<float, CudaFree> data_device;
        std::array<int, 2> shape;
    public:
        Image(/* ? */)
          : data_device(cudaAlloc()/* ? */), 
            shape(/* ? */) 
        {/* ? */}
        // similarly other constructors
        // other members
        // implicit destructor does the right thing
};
0 голосов
/ 21 декабря 2018

Но я должен иметь дело с массивом STL?

Нет, вы не должны.

std::array деструктор уничтожает каждый элементмассива автоматически.

...