Boost logo

Boost :

From: Wesley W. Terpstra (terpstra_at_[hidden])
Date: 2002-11-19 10:35:36


On Sun, Nov 17, 2002 at 07:09:00PM +0000, Dave Harris wrote:
> The benefit is encapsulated single-step construction without unnecessary
> copying. As far I can tell, you have in mind either:
>
> MyMember member1, member2;
> ar >> member1 >> member2;
> const MyClass mine( member1, member2 );
>
> or perhaps:
>
> MyMember load_myclass( basic_iarchive &ar ) {
> MyMember member1, member2;
> ar >> member1 >> member2;
> return MyClass( member1, member2 );
> }
>
> const MyClass mine( load_myclass( ar ) );
>
> Both of these involve extra copying. The first involves breaking
> encapsulation of MyClass, because the caller needs to know about all of
> MyClass's members. The second is more encapsulated (at the cost of yet
> more copying of the data) but still has load_myclass() doing the work that
> really belongs in the constructor.

I think you may be interested to run this program:

#include <iostream>
using namespace std;

struct A {
         const int y;

        A() { cout << "Construct" << endl; }
        A(const A& a) { cout << "Copy" << endl; }
        ~A() { cout << "Destroy" << endl; }

        A(int x) : y(x) { cout << "Explicit construct" << endl; }
};

A foo() {
         int somevar = 3;
        return A(somevar);
}

int main() {
         A boo = foo();
        return 0;
}

Observe the *absence* of copies.
Therefore both examples you give above only need to copy the constructor
parameters, never the object. I am using g++ 2.95.4 and 3.2, however I think
this behaviour is also in VC++ and possibly specified in the standard.

> Constructors should construct. With the single-step approach, a load
> function (if desired) could look like:
>
> void MyClass::load( basic_iarchive &ar ) {
> MyClass( ar ).swap( *this );
> }

*This* might copy three times. (at least two)
So, no better, and probably worse than above.

> > Your method would require that every class that uses serialization
> > and but no default constructor have code in it that knows about
> > archives. Non intrusive serialization could be be implemented in
> > this case.

That is not the case; his solution allows making the serialization method as
a template specialization. It could construct the object however necessary.

> Incidently, for some classes the MyClass( MyMember, MyMember ) constructor
> would have to be added specifically for serialisation anyway. We are
> serialising the /internals/ of the class. Those internals won't
> necessarily form part of the public interface.

I think you have a really good point here. :-)
OTOH, there is nothing he can do about this case.
This is the price of data hiding.

---
Wes

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