Да, удаление Foo*
из контейнера уничтожает Foo*
, но не освобождает Foo
.Уничтожение необработанного указателя - всегда - нет операции.Другого не может быть!Позвольте мне привести несколько причин, по которым:
Класс хранения
Удаление указателя имеет смысл только в том случае, если указатель фактически был выделен динамически, но как может среда выполнения узнать, так ли это, еслипеременная указателя уничтожена?Указатели также могут указывать на статические и автоматические переменные, и удаление одного из этих выводов неопределенное поведение .
{
Foo x;
Foo* p = &x;
Foo* q = new Foo;
// Has *q been allocated dynamically?
// (The answer is YES, but the runtime doesn't know that.)
// Has *p been allocated dynamically?
// (The answer is NO, but the runtime doesn't know that.)
}
Висячие указатели
Нет способа выяснить,Пуанти был уже выпущен в прошлом.Удаление одного и того же указателя дважды приводит к неопределенному поведению .(Он становится висящим указателем после первого удаления.)
{
Foo* p = new Foo;
Foo* q = p;
// Has *q already been released?
// (The answer is NO, but the runtime doesn't know that.)
// (...suppose that pointees WOULD be automatically released...)
// Has *p already been released?
// (The answer WOULD now be YES, but the runtime doesn't know that.)
}
Неинициализированные указатели
Также невозможно определить, была ли вообще указана переменная-указатель,Угадайте, что происходит, когда вы пытаетесь удалить такой указатель?Еще раз, ответ: неопределенное поведение .
{
Foo* p;
// Has p been properly initialized?
// (The answer is NO, but the runtime doesn't know that.)
}
Динамические массивы
Система типов не различает указатель на один объект (Foo*
)и указатель на первый элемент массива объектов (также Foo*
).Когда переменная-указатель уничтожается, среда выполнения не может выяснить, следует ли освободить указатель через delete
или через delete[]
.Выпуск через неправильную форму вызывает неопределенное поведение .
{
Foo* p = new Foo;
Foo* q = new Foo[100];
// What should I do, delete q or delete[] q?
// (The answer is delete[] q, but the runtime doesn't know that.)
// What should I do, delete p or delete[] p?
// (The answer is delete p, but the runtime doesn't know that.)
}
Сводка
Так как среда выполнения не может сделать ничего разумного с pointee, уничтожение переменной указателя равно всегда нет опер.Ничего не делать определенно лучше, чем вызывать неопределенное поведение из-за неосведомленного предположения: -)
Совет
Вместо необработанных указателей рассмотрите возможность использования интеллектуальных указателей в качестве типа значения вашего контейнера, поскольку они принимаютответственность за освобождение пуантина, когда он больше не нужен.В зависимости от ваших потребностей, используйте std::shared_ptr<Foo>
или std::unique_ptr<Foo>
.Если ваш компилятор еще не поддерживает C ++ 0x, используйте boost::shared_ptr<Foo>
.
Никогда , повторяю, НИКОГДА НЕ используйте std::auto_ptr<Foo>
в качестве типа значенияконтейнера.