Qt и auto_ptr

Я только что открыл для себя концепцию 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 ответа

Решение

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

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

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

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

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

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

// Destroyed here.

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. Они могут быть скопированы и, следовательно, могут помещаться в контейнеры.

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