boost::привязка и удаление

#c #boost #bind

#c #boost #привязка

Вопрос:

Мне нужно сопоставить a delete ptrAddr; с a boost::function0 , но у меня возникают некоторые проблемы с выполнением этого для удаления. free работает просто отлично. Проблема, похоже, в std::ptr_fun(operator delete) но я не могу понять, как заставить это работать без написания вспомогательного функтора.

 boost::function0<void> Function;
Function = boost::bind(std::ptr_fun(free), (void*)malloc_string);  //this works
Function = boost::bind(std::ptr_fun(operator delete), (void*)new_string);  //doesn't work
Function();  //call function
  

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

1. при работе с пользовательскими типами указатель this скрыт. также он вызывает деструктор перед удалением выделенной памяти. Не смешивайте new / delete с malloc / free

Ответ №1:

Вы можете использовать delete_ptr из Boost.Лямбда:

 boost::bind(boost::delete_ptr(), new_string);
  

В C 11 вы можете использовать std::default_delete<T> :

 std::bind(std::default_delete<decltype(new_string)>(), new_string);
  

Или просто лямбда:

 [new_string]() { delete new_string; }
  

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

1. должен ли я выполнять выделение через new_ptr , чтобы использовать delete_ptr ?

2. @cprogrammer: Нет, new_ptr определено для использования new T(args) , и delete_ptr определено для использования delete T , потому что, ну, в противном случае не имеет особого смысла поступать иначе.

3. есть идеи, почему я получаю bind.hpp (69): ошибка C2039: ‘result_type’: не является членом ‘boost:: lambda::delete_ptr’?

4. Я использовал boost / bind вместо boost / lambda / bind. спасибо cat

Ответ №2:

delete p; это не вызов функции; это выражение. То, что вы хотите, не имеет смысла.

Действительно существует бесплатная функция ::operator delete() , но она не делает того, что вы думаете.

Посмотрите на реализацию любого стандартного библиотечного контейнера (ключевое слово: распределитель) или, возможно, std::unique_ptr , чтобы увидеть, как выполняется удаление настраиваемого объекта.


Типичная последовательность построения / уничтожения, разбитая на части, выглядит следующим образом:

 void * addr = ::operator new(sizeof(T));  // allocation

T * p = ::new (addr) T;                   // construction

p->~T();                                  // destruction

::operator delete(addr);                  // deallocation
  

Первые шаги to морально эквивалентны выражению T * p = new T; , в то время как последние соответствуют delete p; . Однако нет другого способа вызвать конструктор, кроме как через new выражение; и вы не должны забывать вызывать деструктор тем или иным способом.