Re: Exception unwinding base destructor called - why?
From: Douglas Peterson (Tergiver_at_nospam.msn.com)
Date: 06/24/04
- Next message: fabio de francesco: "errors = templates * friends;"
- Previous message: Phlip: "Re: Refactoring tool... PLEASE"
- In reply to: John Harrison: "Re: Exception unwinding base destructor called - why?"
- Next in thread: Douglas Peterson: "Re: Exception unwinding base destructor called - why?"
- Reply: Douglas Peterson: "Re: Exception unwinding base destructor called - why?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Thu, 24 Jun 2004 14:08:45 -0400
"John Harrison" <john_andronicus@hotmail.com> wrote in message
news:2k0h3oF14v5vdU1@uni-berlin.de...
>
> "Douglas Peterson" <Tergiver@nospam.msn.com> wrote in message
> news:P92dndYQSsjubUfdRVn-jw@comcast.com...
> > Thanks to Andre, John, and David for taking the time to reply.
> >
> > After your explanations and giving it more thought, I accept that a
fully
> > constucted object needs to be deconstructed. Makes perfect sense when
you
> > look at it outside of the problem your having :)
> >
> > Here's what the issue was and how I'm going to change it:
> >
> > The objects in my system are all contained in lists. There is a root
item
> > with a list of objects, those objects contain a list of objects and so
on,
> > and so on.
> >
> > I wanted two properties for objects that are contained in this system:
> >
> > 1) Objects could be created externally so that they can be further
derived
> > by the user. That is to say you don't call Container.CreateObject() to
> > create one, you can 'new Object'.
> > 2) Objects would automagically be added and removed to/from the
containers
> > they belong to.
> >
> > To accomplish #2, the constructors of the object's deepest base class
were
> > adding and removing themselves to their owner's lists. When an exception
> > occurs during object construction, one of two possibilities occurs
> depending
> > on what point the exception is thrown:
> >
> > 1) The object has been added to the container's list, but doesn't
(can't)
> > remove itself when its not getting fully constructed. This leads to an
> > attempt by the container to delete an already deleted object.
> > 2) The object isn't yet added, but its destructor tries to unlist
itself.
> >
> > Number 1 can be solved by placing the 'insert myself into my owner's
> > container' line of code dead last in the constructor. That way if an
> > exception occurs during its construction, its not added. If the
exception
> > occurs in a derived class, we get number 2 because the base is fully
> > constructed and will be destructed.
> > Number 2 is benign, however, my container list code asserts because in
> most
> > cases the programmer wants to know that his code is trying to remove
> > something that isn't there (a potential bug).
> >
> > So I'm left with a choice:
> >
> > 1) Remove the automagic and require all objects to be inserted after
they
> > are constructed.
> > 2) Remove the assertion from my list class to allow for benign attempts
at
> > removal.
> >
> > I'll elicit some respones before making a descision.
> >
>
> I don't understand the problem, its seems to me that C++'s rules are
helping
> you, but you seem to think that they hinder you.
>
> Here's how I see it, the deepest base class ctor adds to the list, the
> deepest base class removes from the list. Nothing else happens in the
> deepest base class ctor and dtor.
>
> So when an object is constructed the first thing to happen is that the
> deepest base class ctor is called. If it constructs successfully then the
> object is on a list and the deepest base class dtor will remove it from
that
> list should an exception be thrown later during construction. If by chance
> an exception happens while adding to the list, then the object isn't in
the
> list but the dtor won't be called because the deepest base class wasn't
> fully constructed. Isn't that exactly what you want?
>
> Seems straightforward to me, maybe you could make the problem clearer with
> some sample code.
>
> john
The problem with that is the deepest base can't insert itself without
knowledge of the container. It has to call some kind of insert/remove
method. Here is some pseudo code of the system:
class ItemOne : public LinkedItem<ItemOne>
{
ItemOne(Owner* owner)
{
owner->itemOneList.Insert(this);
}
~ItemOne()
{
owner->itemOneList.Remove(this);
}
};
class Owner
{
// notice that the owner can contain lists of more than one different
kind of object
LinkedItemList<ItemOne> itemOneList;
LinkedItemList<ItemTwo> itemTwoList;
};
What your saying, is have (for example) the LinkedItem<> class do the
insert/remove and that would be ok, except LinkedItem<> would have to be
passed a pointer to the LinkedItemList<> it will get inserted into. Not so
bad, but it has to cache that pointer in order to call Remove on
destruction. That's yet another 4 bytes per item wasted. I say wasted
because the derived class is going to cache a pointer to its container and
the derived class is aware of which list it belongs in so that's 4 (or 8)
redundant, wasted bytes. One pointing to the container and one pointing to a
member of the container all in the same aggregate object.
Its a very good idea, I just have to convince myself that its ok to waste
bytes for the benefit of the programmer (as opposed to for the benefit of
the program). I could remove the automagic insert/remove code and leave the
onus on the programmer to do it properly. I suppose for most people this is
a non-issue, but I come from the world of embedded systems programming and
old habits die hard.
- Next message: fabio de francesco: "errors = templates * friends;"
- Previous message: Phlip: "Re: Refactoring tool... PLEASE"
- In reply to: John Harrison: "Re: Exception unwinding base destructor called - why?"
- Next in thread: Douglas Peterson: "Re: Exception unwinding base destructor called - why?"
- Reply: Douglas Peterson: "Re: Exception unwinding base destructor called - why?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|