Страницы

Поиск по вопросам

пятница, 14 февраля 2020 г.

Освобождение памяти void* var

#cpp #указатели


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

class UC{
private:
    void *var;
    ...
public:
    template
    UC(const T& tmp){
        var = new T;
        (*(T*)var) = tmp;
    }
    ~UC();                // ?
    ...
};

    


Ответы

Ответ 1



Это сильно напоминает std::any. Вам нужно в каждом объекте хранить указатель на функцию, которая будет удалять ваш указатель, предварительно скастовав его к T *. А выбирать правильную функцию нужно в шаблонном конструкторе. Вот так: class UC { private: void *var; void (*del_func)(void*); public: template UC(const T& tmp) { var = new T(tmp); del_func = [](void *p){delete static_cast(p);}; } ~UC() { del_func(var); } }; Я заменил var = new T; (*(T*)var) = tmp; на var = new T(tmp);. Так проще. Кроме того, очень советую почитать про the rule of three.

Ответ 2



Наверно я показываю плохой способ, но возможно обойтись вообще без явного деструктора :) Если использовать класс shared_ptr из STL: class UC { private: shared_ptr var; public: template UC(const T& tmp) : var { new T { tmp }, [](T * v) { delete v; } } { } void * getVar() { return var.get(); } }; int main() { string s { "test" }; UC test { s }; void * z = test.getVar(); cout << *((string *)(z)) << endl; } P.S.: вообще-то shared_ptr предназначен не для этого, но уж очень хорошо его функционал подходит :)

Комментариев нет:

Отправить комментарий