Мне нужен контейнер указателей, который становится владельцем указателей — т.е. когда элемент удаляется или контейнер выходит из области видимости, он освобождает все свои указатели, как в boost::ptr_vector
,
QList<QScopedPointer<AbstractClass> >
не работает (ошибки компиляции, нет конструктора копирования?).
Щас пользуюсь QList<QSharedPointer<AbstractClass> >
, но это похоже на перебор, с подсчетом ссылок и дорогим мьютексом для многопоточности.
Редактировать: Я только что узнал о QPtrList (спасибо @ForEveR), который был очень похож на Qt3, но был удален из более поздних версий. Я просто не понимаю, почему они убрали бы это.
Вы правы в том, что QSharedPointer немного затянут по указанным причинам.
К сожалению, в Qt такого вектора указателя нет, и также немного сомнительно, стоит ли добавлять его, когда язык развивается, и у нас есть хорошие примитивы для выполнения подобных задач.
Я только что провел небольшое обсуждение с одним из разработчиков ядра Qt, и похоже, что на сегодня рекомендованным решением является либо QSharedPointer, либо это из C ++ 11:
std::vector<std::unique_ptr<AbstractClass>>
Не пытайтесь использовать QVector вместо std :: vector, поскольку QVector может захотеть сделать копии.
Не пытайтесь использовать это решение, даже в C ++ 11:
QList<QScopedPointer<AbstractClass>>
Проблема здесь в том, что QList хочет делать копии. При использовании любого неконстантного метода вызывается detach, который создает копии, а не компилирует.
Кроме того, QScopedPointer не имеет конструкторов или операторов перемещения и это по замыслу.
Еще одна идея, основанная на Qt-концепциях:
Вы можете получить объекты, на которые указывает указатель в списке, из QObject и добавить небольшой класс, основанный на QObect, который содержит владельца списка. Каждый указатель, который будет добавлен в этот список, основанный на новом QObject, должен установить собственный список-класс в качестве своего родителя.
Теперь контейнер списков на основе QObject позаботится об очистке с помощью механизма Qt при его освобождении.
class Ptr : public QObject {
};
class MyList : public QObject {
QList<Ptr> m_myList;
public:
void add( Ptr *item ) {
m_mylist.push_back( item );
item->setParent( this );
}
};
Вы можете найти больше информации о владении деревом объектов Qt здесь: http://qt-project.org/doc/qt-4.8/objecttrees.html .
Конечно, это намного сложнее, чем использование небольшого типа C ++ — 11, такого как std :: unique_ptr.