On 01/12/2013 02:04 AM, Era Scarecrow wrote:
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.
I don't think reference counting would work for my purposes, which is why I wanted a "weak pointer". There will usually be many live references at the time I need to release an item. If I'd had weak pointers I could have made almost all of them weak pointers. I want to release things that are stale, not things that are unreferenced. I was trying to avoid needing to cycle through the entire data structure.


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.
Well, it doesn't exist, so no problem. But what about that is a mistake? I haven't used enough C++ to know. (My recent background is Python, Java, and Ruby...C is way in the background, and the last time I used C++ heavily was before the STL.)


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.
Some of the items have heavy data inclusions, and they would get passed around as pointers, some of them are light, and they'd be structs. Some could be automatically calculated from the creation parameters, others need to be read in from files. And these cause different values returned from functions doing abstractly the same job.


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).
If I'd been able to have actual weak pointers, that would be worthwhile. As it is...I'm going to use references (i.e., class instances) as the external interfaces. Internally, things will often be quite a bit different. (Yeah, maybe I should say handle rather than reference. I'm not sure. I *am* sure I like the syntax of class instances a lot better than I do pointers to structs.)

Reply via email to