Boost logo

Boost :

Subject: Re: [boost] [serialization] overloading load_construct_data: no accessible constructor at all
From: Takatoshi Kondo (kondo_at_[hidden])
Date: 2011-08-13 11:41:58


Hi, Griffin

On Sat, 13 Aug 2011 04:34:39 -0700
Griffin Howlett <griff.howl_at_[hidden]> wrote:

> Hey, so I'm using the boost::serialization library, and I'm trying to
> override how a class is constructed, since it has no default constructor.
> This is demonstrated
> here<http://www.boost.org/doc/libs/1_47_0/libs/serialization/doc/serialization.html#constructors>.
> To me it appears the function ONLY takes the `class* t` and then sets it to
> point to a newly constructed object. If I'm wrong, this is definitely the
> source of my error.
>
> However, the only way to construct my class is by using another classes
> `create()` function, meaning I need to stray from the code in the example
> (this is stated in the boost::serialization namespace):
> `::new(t)my_class(attribute);`

I believe that the load_construct_data's typical usecase is below.

template <class Archive>
inline void load_construct_data(Archive& ar, T* t, unsigned int const /*version*/)
{
    AttributeType* attribute;
    ar >> attribute;
    ::new(t) T(attribute);
}

> I tried simply calling the create function and setting `t` equal to the
> returned pointer, but this doesn't seem to work because right after the
> `load_construct_data function`, and in the `serialization function`, the
> given `myClass&` is not the same as what I set 't' to.

Though you overwrite the `t`, it is no effect to load_construct_data's caller.
Because the `t` is *copy* of a pointer.

> *How do I do whatever ::new(t) is doing so the object created using the
> create function follows through into the serialize/other functions?*

Why do you want to create my_class from another class?
Perhaps custom you want to use custom allocated memory?

See boost/archive/detail/iserializer.hpp:246 (Version1.47)

        struct has_new_operator {
            static T* invoke() {
                return static_cast<T *>((T::operator new)(sizeof(T)));
            }
        };

The serialization library provide the function that calls your
custom operator new.

You can provide custom operator new like that.

struct my_class {
    static void* operator new (size_t size)
    {
        return another_class::allocate(size);
    }
    static void operator delete(void* p)
    {
        another_class::deallocate(p);
    }
};

Your custom new/delete operator would be called from the serialization
library.

If your reason is not custom allocator,
you can provide the my_class's constructor that can call
from load_construct_data instead of another class's create function.

Thanks,
Takatoshi


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