Добавление указателей в QList
мне нужно вставить указатели классов (унаследованных от QObject) в QList. Я знаю, что можно использовать следующий синтаксис:
.h
QList<MyObject*> list;
.cpp
list.append(new MyObject("first", 1));
list.append(new MyObject("second", 2));
...
и затем свободная память:
if(!list.isEmpty())
{
qDeleteAll(list);
list.clear();
}
это должно быть действительным и не вызывает утечек памяти (насколько я знаю). Однако, мне нужно инициализировать объекты, прежде чем добавлять их в коллекцию. Может ли следующий фрагмент кода вызвать некоторые ошибки например, утечки памяти или болтающиеся указатели (я буду использовать тот же способ удаления указателей, что и выше)?
MyObject *obj;
for(i = 0; i < 5; i++)
{
obj = new MyObject();
if(!obj.Init(i, map.values(i)))
{
// handle error
}
else
{
list.append(obj);
}
}
спасибо.
4 ответов
Если вы позаботитесь о " obj "(выделенный, но не инициализированный экземпляр) в случае" / / handle error", ваш код в порядке.
вместо этого используйте QSharedPointer.
QList<QSharedPointer<MyObject> > list;
чтобы освободить память, вам нужно только сделать
if(!list.isEmpty())
{
list.clear();
}
добавить в список
list.append(QSharedPointer<MyObject>(new MyObject("first", 1)));
list.append(QSharedPointer<MyObject>(new MyObject("second", 2)));
использовать RAII (выделение ресурсов является инициализацией). Инициализируйте объект непосредственно в конструкторе.
тогда код будет выглядеть так:
for(i = 0; i < 5; i++)
{
list.append( new MyObject( i, map.values(i)));
// In case of initialization failure, throw exception from the constructor
}
можно использовать QScopedPointer..
из документации Qt 4.6,
класс QScopedPointer хранит указатель на динамически выделенный объект и удаляет его при уничтожении. Управление выделенными объектами кучи вручную сложно и подвержено ошибкам, что приводит к утечке памяти кода и трудно поддерживать. QScopedPointer-это небольшой служебный класс, который сильно упрощает это, назначая владение памятью на основе стека куче ассигнований, чаще именуемый приобретение ресурсов инициализация (RAII).
надеюсь, что это помогает..
Edit:
например,
вы будете использовать,
QScopedPointer<QWidget> p(new QWidget());
вместо
QWidget *p = new QWidget();
и добавить QScopedPointer
в своем QList
, не беспокоясь о утечка памяти и висячие указатели.