Почему 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
для), или же отслеживать, какие адреса были удалены, что означает, что они все еще используют какую-то память и не освобождены. ]