Добавление указателей на QList - PullRequest
7 голосов
/ 15 июля 2010

Мне нужно вставить указатели классов (унаследованных от 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 ]

5 голосов
/ 15 июля 2010

если вы позаботитесь о «obj» (выделенном, но не инициализированном экземпляре) в случае «// обработки ошибки», ваш код в порядке.

3 голосов
/ 17 мая 2017

Используйте взамен 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)));
0 голосов
/ 15 июля 2010

Вы можете использовать QScopedPointer ..

Из документации Qt 4.6,

Класс QScopedPointer хранит указатель на динамически размещенный объект и удаляет его при уничтожении. Ручное управление объектами, выделенными из кучи, является сложным и подверженным ошибкам, что приводит к общему утечке памяти из-за недостатка памяти. QScopedPointer - это небольшой служебный класс, который значительно упрощает это, назначая владение памятью на основе стека выделению кучи, более широко называемое получение ресурсов - инициализация (RAII) .

Надеюсь, это поможет ..

Edit:

Например,

Вы будете использовать,

QScopedPointer<QWidget> p(new QWidget());

вместо

QWidget *p = new QWidget();

и добавьте QScopedPointer в ваш QList, не беспокоясь о утечке памяти и висячих указателях.

0 голосов
/ 15 июля 2010

Использовать 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
}
...