On 01/11/2013 01:12 PM, Era Scarecrow wrote:
On Friday, 11 January 2013 at 18:22:30 UTC, Charles Hixson wrote:
I was looking for a way to create a weak reference to either a struct
or a class. I need to be able to use it to automatically generate an
active reference on access. (I intend to do this by rolling in data
from a file.)

Any guidance as to where I should look?

Looks like you'll have to create the access yourself, you can forward
access to the new ptr via a property call by the function you name. This
works.

struct S {
int x;
S* _s; //for weak ptr.

//constructor details so we can show it's
//differences in the lower prints.
S* s(int x) {
if (_s is null)
_s = new S(x);

return _s;
}

void print(){writeln(this);}
}

S test;
test.print();
test.s(10).print();
test.print();


I've tried making a weakPtr template function, however it complains
about a nested function call (perhaps cause it was within a unittest);
Shows the problem(s) on that side.

It's possible to write a mixin that could do those details for you.

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

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

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

Reply via email to