[openbeos] Re: Pointer or reference?

  • From: Timothy Scriven <batty_ousemoosik@xxxxxxxxxxxxxxx>
  • To: openbeos@xxxxxxxxxxxxx
  • Date: Wed, 31 Mar 2004 17:58:59 -0800 (PST)

> First, I would not want my objects to automatically be destroyed when 
> they
> are removed from the hierarchy, because I may want to use the object
> somewhere else.

Wouldn't you instantiate a new instance of the object in that case?


________________________________
Timothy Scriven
+61409926381

batty_ousemoosik@xxxxxxxxxxxxxxx



--- "Eric J. Mislivec" <emislive@xxxxxxxxxxxxxxxxxxxxx> wrote:
Hi all,

I've been reading messages in this thread for awhile and figure it's 
time to add my own 2 cents...

> > >Unfortunately, the BeAPI adds more places where pointers must be 
> > > used
> mainly
> > >because some BeAPI objects delete themselves (why anyone would 
> > > make
> objects that
> > >behave like that is beyond me).
> >
> > Actually, this is a good thing. Other environments work too like 
> > this. In
> delphi, for example, objects delete themselves if they are part of a 
> visual
> hierarchy. Otherwise you would have to keep track of all the objects 
> (mostly
> views) you add (or keep a pointer to them in the parent class, which 
> isn't
> needed, since you can use FindView() instead).
> 
> First, I would not want my objects to automatically be destroyed when 
> they
> are removed from the hierarchy, because I may want to use the object
> somewhere else.

In situations where a child object is added to a parent, the assumption 
is that the parent takes ownership of the child object, and thus should 
be responsible for deleting it. When you remove an object from the 
hierarchy, you are reclaiming ownership of it as well as the 
responsibility for deleting it. Since it has been removed from the 
hierarchy, the parent should no longer have a pointer to it and can not 
delete the removed child.

> I'm not familiar with these other API's, however I still say it's a 
> bad
> thing.  For one thing it forces you C++ differently then it was 
> intended.
> Objects you explicitly allocate memory for should be explicitly 
> deallocated.
> The biggest issue this introduces, is that you can't trust any 
> pointer to
> the object.

Pointers to child objects should be entirely trustworthy until the 
parent is deleted, which is normally pretty evident. Objects don't just 
randomly delete themselves, or delete themselves at 4pm on a Wednesday, 
you have to do something to lead up to it. When you do something that 
will cause an object to be deleted you can assume its owned children 
will be deleted.
 
> You would have to manually destroy objects you created dynamically.  
> Which,
> of course could be done by using FindView() or a stored pointer.  
> For, the
> few cases where it would be more convenient to create a object 
> dynamically
> it would also be more convenient to store the pointer rather then 
> repeated
> use if FindView().  For the majority of the time your could just 
> create
> objects on the stack and they will be implicitly destroyed when the 
> parent
> is destroyed.

The stack isn't the answer, especially in Be. From my viewpoint the 
reason why the BeAPI uses so many pointers is not an ownership issue, 
but rather a multithreading issue. This is also why creating objects on 
the stack is incorrect. An automatic (stack) variable can only be 
accessed from the thread that created it. Since a BApplication's 
message loop is run from the main program thread, and each BWindow's 
message loop run in its own thread, you have to allocate memory that 
they both need to access on the heap. Memory allocated on the heap is 
most conveniently accessed with pointers. Also, in a multithreaded 
environment, stack space needs to be used more conservatively since the 
stack is split up between threads, with the stack size limited by the 
difference between the starting address of one thread's stack and the 
starting address of the next thread. On BeOS "the stack size is fixed 
at around 256k." A real easy way to crash your program would be to 
create a 256k object on the stack.

On the topic of references vs. pointers, references are a good way of 
implying that "this data should only be accessed from this thread!" Say 
for instance that MessageReceived() took a reference to a BMessage 
created on the stack as opposed to a pointer to a message on the heap. 
Now say that you want to have a few slave threads do something with the 
data in the message, and have them signal you when they are finished 
accessing its data, at which point you return from MessageReceived(). 
With a reference to a message on the stack you would have to make a 
copy of the message (or the relevent data) on the heap and use that. 
Another annoying effect of this would be to limit messages to less than 
256k in size, a limit that would change depending on stack usage. While 
this scenario of controlling slave threads from MessageReceived() isn't 
very likely, and isn't necessarily a good idea, I hope it illustrates 
some of the issues of retreating to the stack.

To summarize, heap == thread friendly, stack == thread's worst 
nightmare.


> The only time where automatic deletion of any kind is ok is in 
> garbage
> collection.

Automatic deletion is perfectly fine if it is documented, and it is the 
about the only correct way to handle deleting ownership hierarchies. It 
is also a good example of the DRY (Don't Repeat Yourself) principle. If 
a parent didn't delete its children, every application using that API 
would have similar code to walk the hierarchy and delete the children, 
a massive repetition of code.


Peace,
Eric Mislivec



Other related posts: