Boost logo

Boost :

From: Robert Ramey (ramey_at_[hidden])
Date: 2003-10-05 13:23:47


>Did you consider separating out allocation in this second case?
>Specifically, adding an function which just does construction and loading,
>with a default implementation like:

[snip]

I didn't consider such a system.

Looking at it now, (leaving aside the non-portability of reinterpret cast) I don't
think it adds anything to the system and makes it harder to understand
and explain. Of course that's a subjective assesment so I can't defend
it on technical grounds.

>We can probably improve on copying the object into the vector by using
>move semantics. Where we have a C array, we can probably allocate it as
>bytes and construct the objects in-place.

Since arrays are of fixed size and always exist the whole issue doesn't come
up. Of course an array allocated on the heap and handled through a pointer
is a different thing but we're back the the case of serialization through
a pointer so no special consideration is necessary.

>I think your initial instincts were right. Some classes should not have a
>default constructor, not even a private one. Nobody, not even
>serialisation, should have the ability to create the class in an invalid
>state.

>It complicates the class invariant. In effect we would have two class
>invariants, a normal one from the normal constructor, and a "special" one
>from the private default constructor. This affects two functions: the
>destructor, and the pointer version of load. Both of these would have to
>know which constructor was used to construct their object.

>It may not be a big deal in practice but we should avoid this situation if
>we can. I think load_construct does that.

As I said before my personal preference is that objects never have an invalid state.
I've found that any thing that uses STL sometimes copies things without my
being aware of it so its the only way I can have confidence that i don't have
another obscure bug to find. Havng said that, don't think that its a good idea for
a serialization package to enforce this point of view.

In practice I would

a) make the program
b) discover that I need a default constructor
c) think about why I need that
d) decide whether to change the design or "break a rule"

If I decide d) then there's no need to subject myself to any more
discomfort than necessary. Reviewing my normal method of
going about things, I concluded that my original concern of
accidently short circuiting C++ design constraints wouldn't occur.
So I'm inclined not to fight it.

>It may not be a big deal in practice but we should avoid this situation if
>we can. I think load_construct does that.

the load_construct would still have to gain access to a private default
constructor so I don't see that it addresses the original concern
raised by Vladimir.

As an extra aside to keep the pot boiling. I believe the current system would
permit the following override for a given class X

  
    template<class Archive ar,>
    void load(Archive & ar, X * &x, unsigned int file_version)
    {
        char *p = NULL;
        try{
            x = new X(ar);
        }
        catch(...){
            delete p;
            throw;
        }
    }

which would permt the constructor to take the parameters right off the top of the
archive and avoid any special copying. Someone raised this possibility
before ( I think it may be you) I sort of dismissed it but I believe
now that it would be accomodated by the current system by means of the
above override. It might be of use in certain situations where copying
the constructor parameters is somehow inconvenient.

Robert Ramey


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