[Qt-interest] Handle object deletions right with containers (not-working stripped example)

Bo Thorsen bo at fioniasoftware.dk
Mon Aug 8 15:05:04 CEST 2011


Den 08-08-2011 14:34, Wilhelm skrev:
> Hi,
>
> Am 08.08.2011 13:46, schrieb Bo Thorsen:
>> First of all, you are correct that you have to call beginRemoveElement
>> before deleting your object, unless you work around this. You could for
>> example mark an object being deleted as unavailable, so if one of the
>> views or proxies call data() or something else, you just return default
>> values for it. That's a workaround that often works with these pointer
>> based models.
>
> yes, I thought of this too, but this leads to other problems.

Correct, but you have to realize that you *will not* find an ideal 
solution to this problem.

There are other ways, though. For example, make the destructor private 
and add a static public destruct(C* theThis) method that calls a 
function on the object which emits a destroyed() signal and then calls 
delete this.

I can give you more ideas to solve this, but all of them have one thing 
in common: It's not an ideal solution without any issues.

> If the contained objects are removed the "normal" way, e.g. calling a
> remove()-method, this works.
>
> If the contained objects are deleted "outside", this approach requires,
> that the container (model) caches some information about the deleted
> objects, because at the moment the destroyed() signal is emitted, the
> subclassed-parts aren't available anymore. If you call
> beginRemoveElements() (as in the QAbstractItemModel example) in that
> moment, the rowsAboutToBeRemoved() signal is emitted, what in turn
> triggers interested objects (views) to query information and they assume
> to get the state *before* the removal but the detail information isn't
> available anymore ...

Yes, but AFAIK, there is no way to avoid it. You should just return some 
dummy values for the deleted objects. Caching the information is 
normally not feasible, if it is, your problem goes away.

>> To me this looks like an example where I would not use a signal slot
>> connection for the deletes. Instead, as the first thing you do in the
>> destructor of the contained object, call the deletingObject(this) on the
>> model and do the removes.
>
> Well, that requires tightly coupled classes (the contained object must
> know the container).

That's not true. You can de-couple this by using an interface (a 
standard visitor pattern).

Contained::~Contained() {
  foreach (DeleteListener* dl, deleteListeners)
   dl->aboutToDelete(this);
}

> Therefore this approach isn't feasable.

I strongly object to OO dogma that says tight coupling is just bad. 
Tight coupling when unnecessary, is bad. But if you have no ideal 
solution to a problem, you go with a less ideal solution.

Now, that's just my general POV. It could be that you didn't offer 
enough information here and that's it valid to say that tight coupling 
isn't feasible *in this case*. There are plenty of reasons why this 
could be the case.

Bo Thorsen,
Fionia Software.

-- 

Expert Qt and C++ developer for hire
Contact me if you need expert Qt help
http://www.fioniasoftware.dk



More information about the Qt-interest-old mailing list