Почему boost::scoped_ptr или std::unique_ptr не копируются?

В boost::scoped_ptr говорится: "Он предоставляет базовую возможность" получения ресурсов - инициализация ", без семантики совместного владения или передачи собственности". Это делается через какой-то не копируемый механизм.

Мой вопрос: почему существует требование об отсутствии совместного владения?

Вот что я имею в виду:

 template <typename T>
 class my_scoped_ptr
 {
 public:
  // constructor  implemented not shown here
  // operator*() implemented not shown here
  // operator -> implemented not shown here
  ~my_scoped_ptr()
  {
   delete my_p;
   my_p = NULL;
  }
 private:
  T * my_p;
 };


 void foo()
 {
  my_scoped_ptr<someclass> p (new someclass());
  my_scoped_ptr<someclass> q (p); // both p & q point to same my_p object
  // may be an exception is raised
 }

Хорошо, теперь, независимо от того, было ли вызвано исключение, my_p будет удален. поэтому, когда код выходит из области действия foo... вызывается деструктор my_scope_ptr p, удаляющий my_p и устанавливающий my_p в значение null. Теперь снова вызывается деструктор my_scope_ptr q, удаляющий my_p, который на данный момент равен нулю. Кажется, что во время уничтожения меня не волнует, указывает ли оставшийся скопированный указатель на действительный объект.

Итак, почему я должен заботиться о том, что my_scoped_ptr не должен быть копируемым? Я не вижу какого-либо вреда копирования ptr, если ptr позаботится об удалении указанного объекта, как только он выйдет из области видимости.??!!

1 ответ

Решение
void foo()
 {
  my_scoped_ptr<someclass> p (new someclass());
  my_scoped_ptr<someclass> q (p); // both p & q point to same my_p object
  // may be an exception is raised
 }

Как функция заканчивается (возврат или бросок) и q выходит за рамки, деструктор для q будут delete someclass объект. Затем сразу после этого, p выходит за рамки и его деструктор будет delete someclass объект снова

Это не действительно для delete один и тот же указатель дважды! (Если не указано new случилось, чтобы вернуть его в то же время).

[И если бы любая реализация C++ пыталась сделать ее действительной, она должна была бы либо связать воедино все необработанные указатели с одинаковым значением (что shared_ptr для), или же отслеживать, какие адреса были удалены, что означает, что они все еще используют какую-то память и не освобождены. ]

Другие вопросы по тегам