Boost logo

Boost :

From: Vladimir Prus (ghost_at_[hidden])
Date: 2002-11-14 03:05:37


Robert Ramey wrote:

>>How's that? I'm I going to use the class from two different problem, I'll use the
>>same header, and the classes will be in the same namespace.
>
>
> I'm refering here to a discussion in The C++ Programming Language sections 8.2.5
> and section 8.2.8.

It would have helped if you described what is discussed here -- I don't have
the book ready. Anyway, I belive different namespace of the same class makes
sense only for legacy code, and is quite rare.

>>However, the mention of GUID gives me a new ground for argumentation. Suppose *I* (i.e.
>>without any help from serialization library), have created two maps:
>
>
>> 1. type_info -> GUID
>> 2. GUID -> factory function
>
>
>>I believe this is enough to correctly serialize/deserialize all classes registered
>>in those two maps. Your plug-in example suggests that load method for the base class
>>should take care of saving GUID and load method should dispatch to the appropriate
>>factory function. I think this only requires extra work from me, and is not needed.
>>In fact, the library might care of it. If a class with declared GUID is saved, than
>>GUID is safed as well. On loading, if object in archive has GUID, you call appropriate
>>factory function and then proceed with loading into created object.
>
>
> Ahhhhhhh - now you've hit the nail on the head.
>
> My conclusion is that there can exist no universal function that automatically transforms
> type_info into a GUID. This is the fundamental problem.
>
> Suppose we set out to create such a function:
>
> Permit me to include my argument for this point from a previous email

<snip>

Agree, there's no a *universal* way to tell that two classes are semantically
the same.

> Now suppose you have a special situation. For example, a suite of programs
> that are in you sole control and you would like to your own "Local cross program
> class identifier". The above argument doesn't apply to this situation. For this
> I created the example "demo_unregistered_pointers". In this case a GUID
> consisting of type_info.name() would work just fine. Archives and code would be portabable
> across all compilers. It would work even for plug-ins - as long as you had control
> over the naming.

Agh... except that I have to implement some code myself... in particular loading
for base classes. This code would be the same for all base classes, and, therefore,
library can and should take care of it.

> As an aside, I double checked into MFC as the details of how it addresses this issue.
>
> Microsoft uses CRuntimeClass basically a wrapper around the class name. This
> is written to the archive. On loading, they look it in the table. Basically using the
> class name as the GUID. Since this system broke down for COM, the used
> the Unique GUID generated by the computer.

These are no news for me.

> My intention in the example was to illustrate give you the facility you want
> without creating a more fundamental problem for others. Also consider that
> this special serialization is required only for base classes of polymophic pointers
> not for every class. typically this would be only a very small number

What are the fundamental problems for others? The scheme I've described is
completely optional.

>>As I was saying all the time, including all of the headers in the project in "main.cpp" is
>>not a reasonable idea for me.
>
>
> They don't have to be in main.cpp. you could include them a registeration.cpp
> that has a function register_types which you call just after any archive
> is created. At least it would all be in one place.

1. I'd still prefer registering a class at the point of declaration/definition, without
    creating this super-file.
2. You'd have to call a function in that file after creating all archives. This is
    just unsafe: calling ctor should be the only initialization.
3. Now, assume the following situation:

    oarchive a ;
    register_polymorphic_types(a); // Here 100 classes are registers

    a << {polymorphic_pointers) ;

    a << {bunch of other data) : // First stored class will have number 101.

    You put the generated file aside, and after a month create a new polymorphic
    class. Then you do:

    iarchive >> a;
    register_polymorphic_types(a) // Here 101 class is registered.

    a >> {polymorphic_pointers} ;

    a >> {other data}: // Here, we see class id 101, which used to be
                      // first class not-registered in register_poly...
                       // a month ago, but now: it's last polymorphic
                      // class.

Unless I'm missing something, but it seems like CLASS IDS ARE NOT STABLE.
This means that if I just add new polymorphic classes, I won't be able
to read previously created archives.

I don't have the time to create a compilable example, but my prior examination of
the code tells me that the above suspicion is true.
        

- Volodya


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