2013-04-11 4 views
9

Мне нужно создать указатели экземпляров класса, и во время компиляции программа не знает, сколько указателей я создам. Для удаления я рассматривал возможность хранения указателей в векторе, а затем их удаление один за другим. Будет ли использование умных указателей более чистым способом? И если кто-то не хочет использовать интеллектуальные указатели, будет ли это использование вектора считаться чистым?Удаление вектора указателей

Минимальный код:

#include <vector> 
using namespace std; 

class Foo { 
public: 
    Foo(); 
}; 
Foo::Foo(){} 
void createFooVector(int nb, std::vector<Foo*> &v){ 
    for(int i=0;i<nb;i++){ 
     Foo* f = new Foo(); 
     v.push_back(f); 
    } 
} 
int main(int argc, char *argv[]){ 
    std::vector<Foo*> v; 
    createFooVector(5,v); 
    while (!v.empty()){ 
     Foo* f = v.back(); 
     v.pop_back(); 
     delete f; 
    } 
} 
+2

Вам действительно нужен контейнер указателей? Не можете ли вы сохранить объекты 'Foo' в качестве значений (' std :: vector ')? Кроме того, не было бы яснее, если бы 'createFooVector' вернул новый вектор вместо того, чтобы изменять значение, указанное в качестве аргумента? –

+0

@LucTouraille Я использую указатель по этой причине: http://stackoverflow.com/questions/15471193/vector-of-virtual-class-are-pointers-the-clean-way-to-go ... это не могло я вижу здесь код, который я здесь показываю, пытался сохранить его минимальным – Vince

ответ

3

Я хотел бы предложить, либо используя boost::pointer_vector, в std::vector<std::unique_ptr<Foo>> или выкатить свой собственный класс Foo менеджера, который держит vector<Foo*> и ухаживает удаления в конструкторе (вы должны увидеть это как «эксперт» решение, и только попытка если вы полностью понимаете безопасность исключений). Вы не хотите делать удаление вручную, что может привести к ошибкам.

+0

Я бы не рекомендовал решение менеджера; Скорее всего, ОП не сделает его достаточно безопасным в отношении исключений ... –

+0

@MatthieuM. Очень верно. Я добавил предупреждение об этом. – juanchopanza

1

Ваш код хорошо. Однако использование интеллектуальных указателей должно быть предпочтительным (меньше кода для записи и гораздо меньше возможностей для ошибок памяти).

1

Будет ли использование умных указателей более чистым способом?

Да.

И если кто-то не хочет использовать интеллектуальные указатели, будет ли это использование вектором считаться чистым?

У меня нет идей, почему кто-то не хочет использовать смарт-указатели в C++, если это не домашнее задание ... Но, я думаю, что лучше использовать что-то вроде boost::pointer_containers в этом случае.

1

Если вы не используете классы, полученные из Foo, а Foo относительно недорого для копирования конструкции, просто используйте vector<Foo>.

Если ваш компилятор поддерживает перемещение семантики, не должно быть проблем.

+1

Не дорого ли строить, я думаю, вы думали о том, чтобы быть дорогостоящим * копировать *. Однако с семантикой перемещения это может быть не очень проблематично ... и если худшее пришло в худшее, можно использовать новый элемент 'emplace_back'. –

+0

@Matthieu Да, перемещение семантики меняет все. Чтобы уточнить, что я имел в виду, чтобы подтолкнуть значение к вектору, вы должны его построить, тогда векторная копия конструирует другую. Я хотел указать на необходимость учитывать построение ценностей в целом. Я буду обновлять, чтобы сказать 'copy construct'. –

Смежные вопросы