Qt и auto_ptr - PullRequest
       31

Qt и auto_ptr

3 голосов
/ 21 мая 2010

Я только что открыл для себя концепцию auto_ptr и она мне нравится! Поскольку Qt часто требует QList или QVector <(некоторый QObject или QWidget) *>, есть ли конкретная причина, по которой следует избегать auto_ptr. Если я прав, это позволяет заменить это:

std::vector<MyClass*> vec;
/* add several elements to the vector and do stuff with them */
for(size_t i=0; i<vec.length(); ++i)
{
    delete vec[i];
}
vec.clear();

с чем-то намного короче (т.е. без очистки)

std::vector<auto_ptr<MyClass>> vec;
/* add several elements to the vector and do stuff with them */
// no need for the delete loop

... Может ли Qt по-прежнему работать с магией общей памяти с auto_ptr? Работает ли автоматическое управление памятью родитель-потомок прозрачно? Спасибо

Ответы [ 3 ]

12 голосов
/ 21 мая 2010

Qt имеет свои собственные классы интеллектуальных указателей, которые во многих отношениях превосходят std::auto_ptr, особенно в том, что некоторые из них могут быть помещены в контейнеры без проблем. std::auto_ptr имеет семантику копирования-передачи прав собственности и поэтому не будет работать должным образом, если вы попытаетесь поместить ее в контейнер.

Попробуйте использовать QSharedPointer. Это умный указатель со счетчиком ссылок, который удаляет содержащийся в нем объект, когда больше не осталось копий умного указателя. В отличие от std::auto_ptr может быть несколько копий одного и того же QSharedPointer одновременно, и поэтому он хорошо работает с контейнерами.

2 голосов
/ 21 мая 2010

Если вы хотите, чтобы контейнер имел владение указателями, посмотрите на контейнеры указателей наддува.

Вы помещаете указатели в контейнер, но, как и другие контейнеры, они затем обрабатываются как обычные объекты, что упрощает их использование со стандартными алгоритмами (т.е. не нужно писать классы-оболочки). Когда контейнер указателя выходит из области видимости, он вызывает delete для всех указателей в контейнере:

boost::ptr_vector<MyClass>   v;
v.push_back(new MyClass(12));

std::for_each(v.begin(), v.end(), DoStuff());

// Destroyed here.
1 голос
/ 21 мая 2010

std::auto_ptr нельзя использовать в std::vector, поскольку std::vector ожидает, что сможет скопировать его содержимое, и вы не можете скопировать std::auto_ptr в обычном смысле. Копирование означает создание двух идентичных вещей, и если бы у вас было два идентичных std::auto_ptr, то, на что они указывали, было бы дважды освобождено, когда они вышли из области видимости. (Вместо этого происходит то, что копируемый из auto_ptr внутренний указатель обнуляется, а тот, в который копируется, теперь является тем, чем раньше был старый.)

Используйте shared_ptr, который часто доступен как boost::shared_ptr или в Visual C ++ std::tr1::shared_ptr, и который будет в стандартной библиотеке C ++ 0x, или используйте все, что имеет Qt. Они могут быть скопированы и, следовательно, могут помещаться в контейнеры.

...