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).