Вложенный класс Streamer
Вложенный класс Streamer - это ядро потокового кода для ваших объектов. Макрокоманда DECLARE_STREAMABLE создает класс
Streamer внутри вашего класса. Это защищенный член, поэтому классы, производные от вашего класса, также могут к нему обращаться.
Streamer - это наследник TNewStreamer, а TNewStreamer является
внутренним для системы потоков объекта. Он наследует две чистых
виртуальных функции:
virtual void Write( opstream& ) const = 0;
virtual void *Read( ipstream& , sint32 ) const = 0;
Streamer переопределяет эти две функции, но не предусматривает для них определений.
Вы должны написать эти функции: Write
должна записывать любые данные, которые нужно считывать обратно
для воссоздания объекта, а Read должна считывать эти данные.
Streamer:GetObject возвращает указатель на потоковый объект.
Обычно функцию Read легче реализовать перед Write. Чтобы реализовать Read, вам нужно знать данные, необходимые для реконструирования нового потокового объекта, и вы должны предусмотреть
разумный способ считывания этих данных в новый потоковый объект.
Затем реализуется функция Write, которая работает параллельно с Read и формирует данные, считываемые позднее Read. Это легче
сделать с помощью специальных операций, предусмотренных в потоковых классах. Например, opstream обеспечивает инсертеры для всех
встроенных типов, так же как и ostream. Поэтому все, что вам нужно сделать для записи любых встроенных типов - это включение их в
поток.
Вам нужно также написать базовые классы. В старых потоках
ObjectWindows и Turbo Vision это делалось путем прямого вызова
базовых функций Read и Write. В том программном коде, который использует новые потоки, это не работает (из-за поддержки версий
класса).
Библиотека потоков предусматривает шаблоны функций, используемых для чтения и записи базовых классов. ReadVirtualBase и
WriteVirtualBase используются для виртуальных базовых классов, а
ReadBaseObject и WriteBaseObject - для невиртуальных.
При написании базового класса не забывайте приводить тип
указателя this. Без приведения типа шаблон функции будет думать,
что он записывает ваш класс, а не базовый. Результатом будет вызов не базовых, а ваших функций Read или Write. Длинная последовательность рекурсивных вызовов в итоге приведет к краху программы.