как правильно уничтожать классы c ++ с помощью умных указателей - PullRequest
2 голосов
/ 23 мая 2019

Я знаю, что в основном удаление требуется, только когда я выделяю что-то, используя new. Тем не менее, я не уверен в том, как освободить умные указатели и те классы, которые содержат умные указатели в качестве своих членов. Итак, как я могу правильно реализовать деструкторы в следующих классах?

template <typename T>
class Array {
public: 
    Array(const unsigned int length){
        T* ptr = (T*)malloc(sizeof(T)*length);
        array = std::shared_ptr<T>(
            new(ptr) T[length], 
            [](T* ptr){free(ptr);}
        );
    }
    ~Array(){
        // Q1 how should I properly implement this destructor?
    }

private:
    std::shared_ptr<T> array;
};

class Example{
public:
    Example(){
        ...
    }
    ~Example(){
        // Q2 how should I properly implement this destructor?
    }
private:
    Array<float> bufferFloatArray;
    Array<float>* bufferFloatArrayPtr;
    std::shared_ptr<float> bufferFloatPtr;
}

Ответы [ 2 ]

2 голосов
/ 23 мая 2019

Умные указатели автоматически вызывают свои деструкторы. Так что вам не нужно реализовывать ~Array(), однако в классе Example вы используете необработанный указатель (Array<float>* bufferFloatArrayPtr), который должен быть правильно освобожден в ~Example().

PS Обратите внимание, что вы допустили ошибку в реализации класса Array. Используйте delete[] ptr вместо free(ptr) в shared_ptr delete-expression , чтобы избежать утечки памяти.

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

Примечание. Ответ от @ gimme_danger относится к старой версии вопроса.Вот ответ для новой версии .


T* ptr = (T*)malloc(sizeof(T)*length);
array = std::shared_ptr<T>(
    new(ptr) T[length], 
    [](T* ptr){ /*...*/ }
);

Сначала вы выделяете часть памяти, используя malloc, затемиспользуйте синтаксис размещения-нового для вызова конструктора T.Вы должны сделать и то, и другое в устройстве удаления.

[](T* ptr) {
    std::destroy_n(ptr, length);
    std::free(ptr);
}

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

...