Is there a weak pointer or references in D?

Era Scarecrow rtcvb32 at yahoo.com
Sat Jan 12 02:04:07 PST 2013


On Saturday, 12 January 2013 at 04:41:00 UTC, Charles Hixson 
wrote:
> Thanks. That looks quite useful.  OTOH, I don't see how the 
> pointer allows an item to be freed.  You probably meant that 
> this was a framework to start development from.

  Correct. To create an object if it wasn't there when trying to 
access it basically. That's what I originally thought you wanted; 
nothing about freeing it.

> And it does show a way to auto initialize a null pointer (but 
> that's not where I'm hung up...rather on how to automatically 
> null the pointer when the last valid reference is discarded. It 
> looks as if reference counting is the only feasible way, which 
> isn't what I want.  I'd need something that the garbage 
> collector cooperated with.  If it hasn't been built already, 
> then a customized approach is better...which doesn't involve 
> weak pointers.)
>
> But others points are well taken.  A weak reference wouldn't be 
> enough by itself, I'd also need to have the garbage collector 
> prefer to collect stale objects.  So what I'll probably do is 
> accompany each item in the structure (Not a struct, but also 
> not just a class. More a collection of structs and classes that 
> work together.) with a sequence counter that's episodically 
> advanced.  Then at some point I decide that anything that 
> hasn't been touched since some particular sequence is to be 
> freed.  And *THEN* I go back through the entire RAM resident 
> structure and either free the items or subtract the current 
> sequence counter value from them, and then reset the sequence 
> counter to the largest remaining value + 1. When freeing, check 
> if the state needs to be saved.

  Hmmmm... I'd just stay with reference counting. If you leave 
scope with a struct it's destructor is handled (and refcounting), 
if it's a class, then it remains 'stale' until the GC collects 
it, then refcounting is updated as everything else is destroyed.

> That's the rough idea.  Weak pointers will make it easier, but 
> no big deal either way. I may follow your guidance on 
> implementing them, but what I was really hoping for was weak 
> references.  Used sort of like:
>
> Item item = weak(new Item(params));

  Best if you don't... A sorta nice idea, but we don't need to be 
duplicating more of C++'s (boost's?) mistakes.

> With Item being a class.  Clearly what weak() returned would 
> need to be an instance of a descendant class of Item.  Then I 
> could simply maintain a LRU cache of Items, and clear out the 
> old ones, but not free them before the garbage collector 
> decided it was time.  The approach I'm now planning on using 
> frees things in a way that is much less sensitive (I suspect) 
> to current memory pressures.  OTOH, I'd need to ensure that 
> Items saved their state (if necessary) before being freed 
> anyway. Handling it "externally" allows this to be ensured by 
> something more definite in timing than a destructor.
>
> Still, your design for a weak pointer makes it quite easy for 
> an instance to be created if missing.  That may be enough 
> advantage that it would be the best way to  proceed.
>
> Also, I'm really not enamored of template functions, though I 
> am certainly aware of their power.  So the design you offered 
> is one that I would prefer over a templated one.  (Besides, 
> each class/struct that I want to have a weak pointer to would 
> have a different way of constructing missing versions.  So the 
> template would need so much customization, that it wouldn't be 
> much benefit.)

  The template one, (should it have worked) would have had a 
signature of:
  T* weakPtr(T, V...)(ref T* ptr, V args); //V being default 
arguments (if any)

  How it would need to be more customizable I don't know; 
Alternatively a delegate could have been included making only a 
lamba needed in key locations.

> The only things I dislike about you design are things I dislike 
> about all designs that use pointers...and I *did* ask for such 
> a design.

  Yes you did. But since you can't use 'ref' as part of a 
variable's signature (outside of function declarations) you'd 
have to to use pointers instead. Just try to be as safe as 
possible. With pointer arithmetic being unsafe and mostly unused 
(unneeded due to the arrays) it's just a matter of allocating and 
accessing the pointer that's safe (or as much as using classes 
anyways).


More information about the Digitalmars-d-learn mailing list