std::vector<void*> vec;
.delete vec[n];
?void __CRTDECL operator delete(void* _Block, size_t _Size) noexcept;
. Он берет только мой указатель, ничего более. это функция-член...
std::shared_ptr<void>
[?]. Если еще будешь использовать std::make_shared
[?], то вообще обойдешься одним выделением памяти.new
/delete
.Функция-член может быть вызвана только с указателем на полный тип (обратите внимание, что std::unique_ptr может быть создан из необработанного указателя на неполный тип)..
Unlike the std::shared_ptr constructors, std::make_shared does not allow a custom deleter.
Он не сможет удалить класс, если ему дать void.
А вот сделать free - да, но это все равно будет утечкой памяти
vector<shared_ptr<void>>
? Ну может я не настолько хорошо понимаю разницу в утечке памяти и ресурса, но она есть. И то, что если я начну использовать такую конструкцию, не позволит мне избежать утечки.class DeleterBase {
public:
DeleterBase() {};
virtual ~DeleterBase() {};
};
template<class T>
class Deleter : public DeleterBase
{
public:
explicit Deleter(T* ptr) : ptr_(ptr) {};
virtual ~Deleter() override {
delete ptr_;
}
private:
T* ptr_;
};
DeleterBase * hldr = new Deleter<A>(new A());
delete hldr;
Вы мне предлагаете не то, и я поясняю почему это не то.
Я говорю - shared_ptr не вызовет деструктор класса. Утечка есть, все плохо.
Проверь этот код. Где в нем утечка и почему в нем не должен вызываться деструктор?- Евгений Шатунов
Предлагаю просто не утверждать того, в чем ты не убедился лично.
Деструктор — это функция-член, которая вызывается автоматически при выходе объекта из области действия или явно уничтожена вызовом deleteот Майкрософт и
member function may only be called with a pointer to a complete typeот cppreference в случае деструктора для std::shared_ptr
using polimorf_ptr = variant<double*, string*, bool*>;
vector<polimorf_ptr> ...; // получается у вас не void*, а polimorf_ptr
void no_destructor(void*) {}
struct PolimorfPtr
{
public:
PolimorfPtr()
: ptr(nullptr) //надеюсь, ты шаришь за двоеточие
{}
PolimorfPtr(const PolimorfPtr&) = delete;
PolimorfPtr(PolimorfPtr&& other) //надеюсь, ны знаешь что такое r-value - ссылка
:ptr(other.ptr),
destructor(other.destructor)
{
other.ptr = nullptr;
other.destructor = no_destructor;
}
//мне лень писать оператор =, оператор *, -> и вот это вот все, надеюсь ты знаешь зачем нужны эти операторы и понимаешь о чем я
PolimorfPtr(void* pointer, void destructor_calling_function(void*) = no_destructor)
: ptr(pointer),
destructor(destructor_calling_function)
{}
void* ptr; //====================================================== тут хранится указатель
void (*destructor)(void*) = no_destructor; //===========тут хранится указатель на деструктор (на функцию, которая вызывает деструктор)
~PolimorfPtr()
{
destructor(ptr);
ptr = nullptr;
destructor = no_destructor;
}
};
Существует два ограничения на использование деструкторов:
Вы не можете взять его адрес.
Производные классы не наследуют деструктор базового класса.
void string_destructor(void* ptr)
{
delete (string*)ptr;
}
. В новом загруженном модуле не string, а class smclss и указатель smclss*. Это можно решить тем, что каст всех указателей идет в модуле, это означает писать кучу кастов в каждом модуле. По-другому нельзя? (string*)ptr
- это каст. Из void* в string*. Если использовать твою идею то это в каждом dll надо писать функцию с кучей кастов. Напримерswitch(type):
case 0:
delete (int*)ptr;
return true;
default:
return false;