问题
A class TaskGroup
mainly contains a list of Task
s. 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:
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 Task
s 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);
}
来源:https://stackoverflow.com/questions/41532952/list-of-iterators-to-collect-entries-from-various-lists