Элемент удален из QList, но статический счетчик существующих объектов не уменьшается - PullRequest
0 голосов
/ 19 февраля 2010

У меня есть вопрос об удалении элемента из QList.

"myclass.h":

class node2D : public QObject
{
    Q_OBJECT

public:
    node2D(){++s_NCount;};
    ~node2D(){--s_NCount;};

    int checkCount(){return s_NCount;};

private:
    static int s_NCount;
};

"myclass.cpp":

int node2D::s_NCount = 0;

"main.cpp ":

void main()
{
    int i,max_el(4);
    QList<node2D*> *Nlist;
    Nlist = new QList<node2D*>;

    node2D controlNode;

    for (i = 0 ;i < max_el ; i++)
    {
        Nlist->append(new node2D);
    }

    cout << "Nlist size before: " << Nlist->size() << endl;
    cout << "Number of nodes before removing: " << controlNode.checkCount() << endl;

    Nlist->clear();
    cout << "NList size after: " << Nlist->size() << endl;
    delete Nlist;
    cout << "Number of nodes after removing: " << controlNode.checkCount() << endl;
}

После выполнения я получаю:

  • Размер NList перед: 4
  • Количество узлов перед удалением: 5
  • Размер NList после: 0
  • Количество узлов после удаления: 5

Меня беспокоит тот факт, что число объектов node2D по-прежнему равно 5 вместо 1.

Конечно, это можно сделать так:

for (i = 0; i < Nlist->size(); i++)
{
    delete (*Nlist)[i];
}
Nlist->clear();

, но не следует ли автоматически удалять объекты node2D, пока Nlist-> clear ()?

Или это происходит только при наличии родительско-дочерних отношений?

Заранее спасибо,

Pawel

Ответы [ 3 ]

3 голосов
/ 19 февраля 2010

но не следует ли автоматически удалять объекты node2D, пока Nlist-> clear ()?

Совсем нет. Что делать, если я хочу использовать эти объекты где-то еще, что в основном для меня. Управление объектами, указанными указателями, которые вы добавляете в список, - ваша забота, а не QList. Управление копиями этих указателей, с другой стороны, касается QList.

2 голосов
/ 19 февраля 2010

В частности, я не знаком с QT, но обычно универсальные контейнеры не удаляют содержащиеся в них указатели на уничтожение, поскольку во многих случаях это не соответствует требованиям программиста. Это работает в C ++ STL, и я не могу себе представить, что в QT это будет работать по-другому.

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

1 голос
/ 17 мая 2017

В QList вы храните только указатели на объект. Поэтому, если вы очистите список, вы удалите ссылку на этот указатель (он же адрес памяти). Если вы хотите очистить объект самостоятельно, вы можете использовать умные указатели. На самом деле, вы должны всегда использовать умные указатели.

Попробуйте вместо этого

void main()
{
    int i,max_el(4);
    QList<QSharedPointer<node2D> > Nlist;


    node2D controlNode; //if you mixt QSharedPointer and objects like this, maybe you are better off using QExplicitelySharedDataPointer or QSharedDataPointer

    for (i = 0 ;i < max_el ; i++)
    {
        Nlist.append(QSharedPointer<node2D>(new node2D));
    }

    cout << "Nlist size before: " << Nlist.size() << endl;
    cout << "Number of nodes before removing: " << controlNode.checkCount() << endl;

    Nlist->clear();
    cout << "NList size after: " << Nlist.size() << endl;
    //delete Nlist;  not needed anymore since the list is not a pointer
    cout << "Number of nodes after removing: " << controlNode.checkCount() << endl;
}
...