scoped_ptr для структуры с замещенным свободным методом - PullRequest
3 голосов
/ 16 июля 2010

У меня есть структура

typedef struct myStruct_st
{
  int a;
}myStruct;

Может быть создано с помощью

myStruct * myStruct_new()
{
  printf("Allocate\n");
  return new myStruct;
}

И удалено с помощью

static void myStruct_free(myStruct * ptr)
{
  printf("Deallocate\n");
  delete ptr;
}

Я хочу, чтобы память, выделенная для структуры, освобождалась автоматически

Для этого я написал шаблон

template <class T>
class scoped_del
{
 public:
  scoped_del(T * p, void (*mfree)(T *)) :
   p_(p),
   mfree_(mfree)
  {
  }

  ~scoped_del()
  {
   mfree_(p_);
  }

 private:

  T * p_;

  void (*mfree_)(T *);
};

И используйте это так

int main()
{
  myStruct * st = myStruct_new();

  class scoped_del<myStruct> ptr_st(st, myStruct_free);

  return 0;
}

Как я могу сделать это более стандартным способом, используя stl или boost?

Ответы [ 2 ]

3 голосов
/ 16 июля 2010

Boost's shared_ptr делает почти то же самое, почти в том же коде.

#include <boost/shared_ptr.hpp>

main() {
    boost::sshared_ptr<myStruct> ptr_st(myStruct_new(), myStruct_free);

    ptr_st->a = 11;
}

Но вы должны подумать, хотите ли вы писать код на C ++ или код на C. Вы используете очень синтаксис в стиле C (typdef struct, class перед объявлениями, вместо конструктора используется «новая функция», вместо деструктора используется «свободная функция»), но вы пометили C ++ и, очевидно, вы используете некоторые функции C ++. Если вы хотите использовать C ++, использовать все его возможности, а если вы не хотите этого делать, то придерживайтесь C. Смешивание этих двух слишком много может вызвать путаницу у любого, кто пытается выяснить ваш код ( и ваши "дизайнерские решения").

1 голос
/ 17 ноября 2011

Я знаю, что это старый пост, но я только что нашел его, и думаю, что другие, вероятно, тоже. Я также ищу умный указатель в стиле auto_ptr, но он принимает объект-удалитель и по той же причине, что и OP, я также использую библиотеку openssl и хочу обернуть ресурс. Я использую boost::shared_ptr s с deleters() для управления объектами openssl, но я обнаружил, что нужно быть осторожным, потому что некоторые вызовы openssl переходят во владение указателями, которые вы передаете им. Это может вызвать проблему, если вы сохраняете его в shared_ptr, потому что тогда вы получите сценарий двойного удаления. Кроме того, семантически я на самом деле не хочу «делиться» владением этими объектами с кем-либо. Мое использование было или "я им владею" или "я хочу передать это кому-то еще".

Новый C ++ 0x unique_ptr<> может предложить решение, но в то же время осторожно использовать shared_ptr с объектами openssl, это может вас укусить.

...