|
Boost : |
From: Ulrich Eckhardt (uli_at_[hidden])
Date: 2003-01-08 06:56:14
#include <hello>
I was recently having a case where I was coupling two objects loosely. Both
needed to know about each other, but the connection was not static, they
sometimes where separated and reconnected somewhere else. For the curious, I
was connecting a propertylist-widget with a container of entries for the list.
I currently fixed the issue by making some friend-declarations, some asserts
and just 'paying attention that it works', but this is of course not
satisfactory. I thus started thinking about a bidi_ptr<> template....
Any suggestions ? Is this a worthwhile idiom ?
cheers
Ulrich Eckhardt
Outline:
- takes two types as template-arguments, the types of the owners that are to
be connected.
- bidi_ptr<>s come in pairs, bidi_ptr<A,B> is complementary to bidi_ptr<B,A>
- every bidi_ptr mainly consists of two pointers, one points to the owning
object (m_owner), the other to the complementary bidi_ptr<> (m_peer)
- assignment is defined as 'void bidi_ptr<A,B>::operator=(bidi_ptr<B,A>&rhs)'
Note that is doesn't return a reference and that 'rhs' is not a const
reference. This is used to 'connect' two peers. Also note that 'a = b' has
the same effect as 'b = a'.
- destruction of either bidi_ptr results in the peer being nulled
- redirecting a pointer to a new peer nulls the former peer
- pointer-like behaviour (*,->,get()) is implemented by accessing
'm_peer->m_owner'
- operator! and conversion to a boolean are mostly copied from
boost::shared_ptr
TODO:
- (how) can I implement that I can connect a bidi_ptr<A, Base> to a
bidi_ptr<Derived,A> ?
- bidi_ptr needs to be initialized with 'this' and store that pointer. I'm a
bit dissatisfied with that, because it effectively doubles the
memory-requirement and is not necessary (oversimplified example: 'owner =
this-0x8') since it should easily be computed.
- I have no idea if operator safe_bool() is properly implemented, because I
don't understand the whys and hows of it, anyone a pointer to the rationale
for it ?
- using assignment for connecting peers warps the 'normal' modus operandi of
assignment, should I rather us an auxillary function ?
- usually, I would make bidi_ptr<B,A> a friend of bidi_ptr<A,B>, because it
needs access to its peers internals in order to not work recursively. This
doesn't work with my compiler if B is the same as A, the compiler complains
that any class is implicitly its own friend. Therefore all data is currently
public.
- what should operator-> or * do when there is no peer attached ?
- provide an implementation that uses a non-template base-class with two
void-pointers, with derived classes only doing the casts. Measure executable
size with and without.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk