PDA

View Full Version : Proper QList usage



space_otter
17th June 2010, 19:51
Should I use QList<MyClass> or QList<MyClass *>? And why doesn't QList support abstract classes? Isn't that an important feature?

I am developing a subclass of QList<MyClass *> called "stack" which adds some extra operations on its objects and is also an item model so it can be viewed. These operations also save a copy of the list into a list of QList<MyClass *>. But when I try to use recalled list, the pointers are invalid! :mad:

Some members of Stack:


QList<QList<DElement*>*> history;
void undo();
QList<DElement> * duplicate();
void nextHistoryStep();

nextHistoryStep is called when an operation is complete. The current state is appended to history. Or so I think :confused: undo is supposed recall the previous state by copying the pointers back.

Here are the functions:

void Stack::nextHistoryStep()
{
history.append(duplicate());
}

QList<DElement> * Stack::duplicate()
{
QList<DElement*> * now = new QList<DElement*>();
for(int i = 0; i < size(); i++)
{
now->append(at(i));
}
return now;
}


void Stack::undo()
{
if(history.size() > 1)
{
this->clear();
// reload from last history
QList<DElement*> * prev = history.at(history.size() - 2);
for(int i = 0; i < prev->size(); i++)
{
append(prev->at(i));
}

emitUpdate();

history.removeLast();
delete prev;
}
}

Deleting a QList destroys that contents too. Is that just the internal pointers (in this case a pointer to pointer) or my actual objects? This code runs without a problem-but the instant that the contents are actually accessed, a segfault occurs. It is possible to delete the unneeded QList without destroying the contents and is this the problem?

Oh, and DElement was originally abstract. It's a generic "element." But this caused a weird compiler error.

wysota
17th June 2010, 20:07
Are you sure the code you posted is correct? It shouldn't compile... QList<DElement> and QList<DElement*> types are not compatible and you are treating them as such, so there is obviously some typo here.

space_otter
18th June 2010, 19:00
Ah, sorry, they should all be QList<DElement *> *.

Will there be a memory leak if I remove "delete prev;"? The Stack destructor deletes the list contents, so I guess not. Removing the line didn't make it work. Seems the pointers are invalid before undo() is called.

Whew! I figured it out. The operators were deleting the objects. Sorry, there was no way you could have known that. I'm developing an arbitrary-precision RPN calculator program. Do you think I should start a sourceforge project? It's still in the very early stages obviously...

space_otter
19th June 2010, 00:50
Does QList support abstract classes though?

SixDegrees
19th June 2010, 00:57
Does QList support abstract classes though?

What do you mean? You can store anything you like in a QList, but if you're trying to store classes derived from some abstract base class, you'll have to store pointers to the base class, not the derived classes themselves. That's how C++ handles such things.

QList itself, however, doesn't care what you store in it, as long as all the elements match the template type.

franz
22nd June 2010, 06:57
Should I use QList<MyClass> or QList<MyClass *>? And why doesn't QList support abstract classes? Isn't that an important feature?

QList doesn't support abstract classes, but pointers to abstract classes are no problem. You cannot instantiate an abstract class and QList has to be able to create the objects to work properly. If you are looking into storing abstract classes you will have to resort to pointers in a QList. I'm pretty sure the std containers don't handle them either.