Я должен вставить указатели классов (наследованный от 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);
}
}
Спасибо.
если вы позаботитесь об «obj» (выделенном, но не инициализированном экземпляре) в случае «// обработать ошибку», ваш код в порядке.
Использовать 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) .
Надеюсь, это поможет ..
Изменить:
Например,
Вы будете использовать,
QScopedPointer<QWidget> p(new QWidget());
вместо
QWidget *p = new QWidget();
и добавить QScopedPointer
в свой QList
, не беспокоясь об утечке памяти и висячих указателях.