Boost logo

Boost :

From: Robert Ramey (ramey_at_[hidden])
Date: 2004-11-21 12:32:43


I've also been thinking about this. My very first attempt a long time ago
was something like:

template<class Archive, class T>
void serialize(Archive &ar, shared_ptr<T> & t){
    T * raw_ptr;
    ar >> raw_ptr;
    t = shared_ptr(raw_ptr); // problem is here - not matched with other
shared pointers that might point to raw_ptr
    // current shared_ptr implementation depends upon an internal pointer to
a shared count.
}

Adding a map in the archive instance to permit shared_ptrs to be "matched
up" would seem to me to solve the problem. So a custom archive which
includeded such a map would be all that was needed I believe. My main
objection to this is coupling the archives to specific data types. I
haven't seen a way to do this in a generic way so that it could handle the
"next" shared_ptr.

> I looked at the implementation of the serialization library. Quite
> complicated and remarkable in its own way. ;-)

I'll choose to take that as a complement.

> The root cause is, in my
> opinion, that you started off with something and then added features as
> requested.

>Had you started with the _requested features_ you might not have
> needed to add the rest. Anyway, to get back to shared_ptr.

Actually I started with the features I felt were missing in all the other
libraries I looked at. Then there were the requested features. They all
fit in a more or less natural spot. There is no feature in there that
someone has not considered really, really indispensible. There is only one
feature that I don't think has been used - that is the extended type info
which doesn't rely on std::type_info. I do get regular feed back. The
draft package on my personal website has been downloaded 3000 times. I
don't know how many times it was downloaded from the yahoo file section.

Every couple of weeks I get feedback from someone congratulating me on
getting it into boost - and giving me an explanation of how their own system
works.

I also get a lot of short explanations on how simple it would be to ...

In incredible amount of time is spent addressing the vagarities of different
C++ implementations. I don't believe that anyone who hasn't done something
like this appreciates the amount of effort this aspect consumes.

> 4. The ability to deserialize a polymorphic object.
>
> Initially I'll deserialize a raw pointer.
>
> The problem with this approach is that the deserialized shared_ptr<T> will
> contain a deleter that will attempt to destroy a T, whereas the original
may
> have had a deleter destroying a Derived.
>
> This can affect users if ~T is inaccessible or non-virtual or if T is
> incomplete.
>
> It is not possible to solve this without help from the library; basically,
> the T* deserializer (which internally operates with void*/type_info pairs)
> will need to be duplicated to return shared_ptr<T> (internally
> shared_ptr<void>/type_info).

That's quite a mouthful - I'll have to think about that.

> 5. The ability to downcast the deserialized shared_ptr<T> to
> shared_ptr<void> pointing to the most derived object.
>
> This can be done with dynamic_pointer_cast<void>.
>
> The external representation of shared_ptr / weak_ptr is as demonstrated by
> the earlier example:
>
> - int pid;
> - (opt) T * px;
>
> where pid == 0 denotes an empty pointer, a newly seen pid denotes a new
> object and is followed by px, and an already seen pid denotes a reference
to
> an existing object.
>
> shared_ptr probably needs to be marked as "never track, unversioned" to
not
> clutter the archive, but I'm not sure what is the official serialization
> library policy regarding std:: types.

I would have to think about that as well. I'm not convinced that you
couldn't just cast to void * and use that to lookup in the map.

I think marking it unversioned would be a mistake as this won't be trivial
in any case. Marking never track is probably a good idea - though in
practice, the default is that things are tracked only if used as pointers.
I doubt anyone will want to serialize a shared_ptr through a raw pointer.
(LOL - I'm being presumptuious again - I can't help myself)

Robert Ramey


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk