List of iterators to collect entries from various lists

99 views Asked by At

A class TaskGroup mainly contains a list of Tasks. I want to collect certain tasks ta1, ta2, tb3, ... from various groups ga, gb, gc, ... and use this list in a display window/class. The choice of tasks for the collection is of no concern for this question.

(As the question is rather conceptual than technical, the examples are mostly pseudo code. Since I'm using Qt in this particular case, I'll be using Qt classes, but the question shouldn't be limited to this case.)

class Task;

class TaskGroup {
    QString name;
    QList<Task> tasklist;
    ...
}

The objects from the text above, ta1 etc, should be understood as "first task from group ga" etc.

Now, this wouldn't be a problem:

QList<Task> collection;
collection.append(ga.getTask(1));
...
collection.append(gb.getTask(3));
...

doSomethingWithTheCollection(collection);

The use case is something like "create tasks organized in lists --> choose certain tasks --> add them to a TO DO list (collection) --> display collection --> fulfill tasks --> delete accomplished task from collection AND its original list one at a time --> repeat". The problem with the aforementioned implementation is that I cannot delete the entry in the original group (not even by passing by reference or pointer), because just the object is part of the collection.

I therefore would need to make the collection a list of iterators!

QList<QList<Task>::iterator> collection;
collection.append(ga.getIteratorToTask(1));
...

Because I can then use the respective tasks via dereferencing and upon completion I can erase it by collection[x].erase(); and they disappear from the original list.

Am I thinking right so far? Or is this even a sophisticated concept?

If there is more than one quest per list in the collection I have to use QLinkedList, because after manipulation of a general QList, iterators become invalid... Should I therefore implement the TaskGroup class with a QLinkedList instead of a QList?

EDIT

While putting that concept into practice, I discovered in disappointment that erase(iterator) is part of the QList class and not of the iterator itself. It seems, I thus cannot delete the entry in the original list, as I wished, via just the iterator... I need the list for that. Is there any solution to that? Maybe using the Java-like QMutableListIterator and its remove() method instead of QList<Task>::iterator? QMutableListIterator has the disadvantage of not supporting "iterator arithemtics". (I don't want to pass the entire list...could I pass a function pointer to the respective QList<Task>::erase() function? I know this sounds crazy but at this point, I want to know if my approach is somehow doable...)

1

There are 1 answers

8
AudioBubble On BEST ANSWER

I think your solution sounds reasonable, and you are correct that you would need to use a QLinkedList to avoid iterator invalidation.

An alternative design would be to give Tasks a back-pointer to the TaskGroup that owns them, and add a method to TaskGroup to remove a Task. The Task can then request that it is removed from the TaskGroup when it has been completed.

Something like the following (which I haven't tried):

void Task::Complete()
{
    parent->RemoveTask(*this);
}

void TaskGroup::RemoveTask(Task& task)
{
    tasklist.removeAll(task);
}