Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Serialization - extended_type_info

Boost , ,

C++ Boost

Serialization

extended_type_info


Motivation
Runtime Interface
Requirements
Models
Example

Motivation

The serialization library needs a system like type_info/typeid() to perform the following functions
  1. given a pointer to a type T discover the true type pointed to.
  2. given an "external" key - determine what type of object to create.

The problem with std::type_info

  • The main function we require - std::typeid() is not available in all environments. Support for this function depends upon runtime typing(RTTI) support from the compiler. This may be non-existent or not enabled for reasons such as a percieved inefficiency.
  • std::type_info includes a string containing type name. This would seem to satisfy 2) above. But the format of this string is not consistent accross compilers, libraries, and operating systems. This makes it unusable for support of portable archives.
  • Even if the type name string could somehow be made portable, there is no guarantee that class headers would be included in the same namespace accross different applications. In fact, including different headers in different namespaces is an accepted method used to avoid namespace conflicts. Thus the namespace::class_name can't be used as a key.
  • There exists the possibility that different classes use different type id mechanisms. The class header might include this information. If we want to import class headers accross applications, it's convenient that the type id mechanism support inter-operability accross different type id systems.

Features

extended_type_info is an implementation of std::type_info functionality with the following features:
  • Builds a set of extended_type_info records - one for each type serialized.
  • permits association of an arbitrary string key with a type. Often this key would be the class name - but it doesn't have to be. This key is referred to as a GUID - Globally Unique IDentifier. Presumably it should be unique in the universe. Typically this GUID would be in header files and be used to match type accross applications. The macro BOOST_CLASS_EXPORT can be invoked to associate a string key with any known type. We'll refer to these types as "exported types"
  • permits the "mixing" of type info systems. For example, one class might use typeid() to find the external identifier of a class while another might not.
Exported types are maintained in a global table so that given a string key, the corresponding type can be found. This facility is used by the serialization library in order to construct types serialized through a base class pointer.

Runtime Interface


namespace boost { 
namespace serialization {
class extended_type_info
{
protected:
    // this class can't be used as is. It's just the 
    // common functionality for all type_info replacement
    // systems.  Hence, make these protected
    extended_type_info(
        const unsigned int type_info_key,
        const char * key
    );
    ~extended_type_info();
    void key_register();
    void key_unregister();
public:
    const char * get_key() const;
    bool operator<(const extended_type_info &rhs) const;
    bool operator==(const extended_type_info &rhs) const;
    bool operator!=(const extended_type_info &rhs) const {
        return !(operator==(rhs));
    }
    // for plugins
    virtual void * construct(unsigned int count = 0, ...) const;
    virtual void destroy(void const * const p) const;
    static const extended_type_info * find(const char *key);
};
} // namespace serialization 
} // namespace boost

Как правило, для каждого типа создается один и только один экземпляр<extended_type_info>. Однако это осуществляется только на уровне исполняемого модуля. То есть, если программа включает в себя некоторые общие библиотеки или DLLS, может быть более одного экземпляра этого класса, соответствующего определенному типу. По этой причине функции сравнения ниже не могут просто сравнивать адреса этого экземпляра, а должны быть запрограммированы для сравнения фактической информации, содержащейся в экземплярах.

<

extended_type_info(unsigned int type_info_key, const char *key);
>

Этот конструктор должен называться всеми производными классами. Первым аргументом должно быть конкретное осуществление. Для этой базы реализации по умолчанию на typeid(), это значение 1. Каждая система должна иметь свое целое число. Это значение используется для обеспечения совместимости различных систем информации типа.

Второй аргумент — это строка const, которая является внешним названием типа, которому соответствует эта запись. Иногда его можно назвать GUID —GlobalUniqueIDentifier. Он передается через архивы от одного вызова программы к другому, чтобы однозначно определить типы, которые содержит архив. Если «экспортный» объект не будет использоваться, эта стоимость может быть нулевой.

<

void key_register();
void key_unregister();
>

Эта система поддерживает глобальную таблицу, которая связывает внешние строки с<extended_type_info>записями. Эта таблица используется при загрузке указателей на объекты, сериализованные через указатель базового класса. В этом случае архив содержит строку, которая просматривается в этой таблице, чтобы определить, какую<extended_type_info>использовать для создания нового объекта.

Эти функции называются конструкторами и деструкторами классов, которые реализуют<extended_type_info>добавление и удаление записей из этой таблицы.

<

const char *get_key() const;
>

Получает ключ для<extended_type_info>экземпляра. Если ключ не был связан с экземпляром, то NULL возвращается.

<

bool operator<(const extended_type_info & rhs) const;
bool operator==(const extended_type_info & rhs) const;
bool operator!=(const extended_type_info & rhs) const;
>

Эти функции используются для сравнения.< extended_type_info >объекты. Они накладывают строгий общий порядок на все записи<extended_type_info>.

<

virtual void * construct(unsigned int count = 0, ...) const;
>

Постройте новый экземпляр того типа, к которому это< extended_type_info >Запись соответствует. Эта функция принимает переменный список до 4 аргументов любого типа. Эти аргументы передаются конструктору типа во время выполнения. Чтобы использовать объект, необходимо объявить последовательность типов для аргументов конструктора. Аргументы для этой функции должны соответствовать по количеству и типу тем, которые указаны при экспорте типа. Эта функция позволяет создавать экземпляры любого экспортируемого типа, учитывая только экспортируемыйГИД, присвоенный BOOST_CLASS_EXPORT. Если эти типы определены в DLLS или общих библиотеках, загружаемых во время выполнения, эти конструкторы могут быть вызваны до тех пор, пока модуль не будет разгружен. Такие модули называютсяплагинами.

<

virtual void destroy(void const * const p) const;
>

Уничтожьте экземпляр, созданный вышеуказанным конструктором.

<

static const extended_type_info * find(const char *key);
>

При наличии ключа строки символа илиGUIDвозвращайте адрес соответствующего<extended_type_info>объекта

.Требования к выполнению

Для использования библиотекой сериализации реализация<extended_type_info>(здесь ETI) должна быть получена из.< extended_type_info >, а также осуществлять

<
template<class ETI>
const extended_type_info *
ETI::get_derived_extended_type_info(const T & t) const;
>

Возврат указателя в экземпляр<extended_type_info>, который соответствует «истинному типу» типа Т. «Истинный тип» — самый низкий тип в иерархии классов. Тип Т всегда можно отлить в «истинный тип» со статическим отливом. Внедрение этой функции будет варьироваться в зависимости от типа системы идентификатора и иногда будет делать предположения о типе T, которые могут быть идентифицированы с конкретной реализацией<extended_type_info>.

<
virtual bool ETI::is_less_than(const extended_type_info &rhs) const;
>

Сравните этот пример с другим, используя ту же реализацию<extended_type_info>.

<
virtual bool ETI::is_equal(const extended_type_info &rhs) const;
>

Сравните этот пример с другим, используя ту же реализацию<extended_type_info>. Возвращение<true>, если указанные типы одинаковы. В противном случае возвращайте<false>

<
const char ETI::get_key() const;
>

Введите внешний ключ (он же GUID) для этого класса.

<
virtual void * construct(unsigned int count, ...) const;
>

Постройте экземпляр соответствующего типа со списком аргументов.

<
virtual void * destroy(void const * const ptr ) const;
>

Уничтожить экземпляр такого типа. Это вызывает правильный деструктор и восстанавливает выделенную память.

Модели

Библиотека сериализации включает в себя две различные реализации<extended_type_info>.

<

extended_type_info_typeid

>реализуется с точки зрения стандартного типа(). Предполагается, что поддержка RTTI включена компилятором.

<

extended_type_info_no_rtti

>реализуется таким образом, чтобы не полагаться на существование RTTI. Вместо этого он требует эксплицитного экспорта всех полиморфных типов. Кроме того, если объект экспорта должен использоваться для сериализации типов через указатели базового класса, эти типы необходимы для реализации виртуальной функции с подписью:<
virtual const char * get_key();
>, которая возвращает уникальную строку наиболее производного объекта этого класса. Эта функция должна быть виртуальной, чтобы реализовать функциональность, требуемую<ETI::get_derived_extended_type_info>, как описано выше.

Пример

Тестовая программа<test_no_rtti>реализует эту функцию с точки зрения< extended_type_info>API выше для возврата экспортного ключа, связанного с классом. Для этого необходимо экспортировать неабстрактные виды. Он также демонстрирует взаимодействие между двумя различными реализациями<extended_type_info>

.Требования к каждому типу

Каждый тип, управляемый системой, должен быть «зарегистрирован» индивидуально. Это достигается путем создания шаблонов. Например, если тип T использует систему type_info, он будет содержать следующий код:<
namespace boost {
namespace serialization {
template
struct extended_type_info_typeid>T>;
template
struct extended_type_info_typeid>const T>;
} // serialization
} // boost
>Для тех, кто использует библиотеку сериализации, этот шаг можно пропустить, поскольку он выполняется автоматически. Библиотека сериализации включает макрос:<
BOOST_CLASS_TYPE_INFO(
    my_type, 
    extended_type_info_typeid>my_class>
)
>, который используется для указания того, какая<extended_type_info>система должна использоваться для данного типа.

<extended_type_info>включает в себя объект для построения экземпляров типов, не зная, какие именно типы. Это делается с помощью функции< virtual void * extended_type_info::construct(unsigned int count = 0, ...) const; >. Например:
<

struct base {
...
};
struct derived : public base {
...
};
...
extended_type_info *eti = extended_type_info::find("my_class")
base * b = eti->construct(...);
>
<construct>берет количество аргументов и до четырех параметров любого типа. Аргументы передаются конструктору «мой_класса». Полный пример этого можно найти здесь

© CopyrightRobert Ramey2005-2009. Распространяется под лицензией Boost Software License, версия 1.0. (См. сопроводительный файл LICENSE_1_0.txt или копию по адресу http://www.boost.org/LICENSE_1_0.txt)

Статья Serialization - extended_type_info раздела может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 18:34:18/0.0057010650634766/0