Добавление указателей в 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, не беспокоясь о утечка памяти и висячие указатели.