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