Is there a weak pointer or references in D?
Charles Hixson
charleshixsn at earthlink.net
Fri Jan 11 20:33:39 PST 2013
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.
More information about the Digitalmars-d-learn
mailing list