2017-01-23 6 views
1

Использования Fortran 95.Неформатированного чтение/записи из производных типов, содержащих указатели

мне нужно сериализовать сложный производный тип (содержащий другие производные типов) с использованием неформатированной записи (в дальнейшем использовать неформатированное чтение, чтобы перезагрузить его).

Самый простой просто

write(lun) myComplexType 

Однако это не работает, потому что тип содержит указатель. Я не беспокоюсь о сохранении указателя (я могу отдельно сериализовать то, на что он указывает, и снова установить указатель на последующую перезагрузку).

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

Есть ли простой способ сделать неформатированную запись, которая игнорирует указатель, и это не требует, чтобы я отдельно обращался к десяткам других вложенных элементов данных - что могло бы дать мне проблему обслуживания?

Если нет простого способа удержать указатель в отдельной параллельной структуре данных, но я не доволен этим, поскольку мне нужно будет убедиться, что они не разделяются или не синхронизируются при передаче в качестве параметров (рассматриваемая структура содержит состояние сложного моделирования, и я действительно хочу сохранить все состояние в одной структуре).

Основная цель - просто сериализовать состояние моделирования в файл с интервалами, чтобы я мог снова запустить симуляцию из сериализованного дампа состояния позже.

ответ

3

Один из подходов состоит в том, чтобы разделить компоненты не указателя на их собственный тип, который затем используется как тип компонента другого типа «обертка», который также содержит указатели.

TYPE :: non_pointer 
    ! Lots of non-pointer components/nested types, etc. 
END TYPE non_pointer 

TYPE :: wrapper 
    TYPE(non_pointer) :: stuff 
    TYPE(xxx), POINTER :: ptr_comp 
END TYPE wrapper 

Ваши операторы ввода/вывода ссылаются на компонент stuff.

TYPE(wrapper) :: my_simulation_state 

WRITE (unit) my_simulation_state%stuff 

Процедуры, как правило, работают с объектами типа обертки, что по-прежнему сохраняет «целое состояние» в одной структуре.

Подходит ли он в зависимости от того, насколько легко извлечь компоненты указателя из существующего типа.

1

Вдохновленный ответом Иана, может быть интересно также рассмотреть наследование для разделения данных без указателя и указателя и написать только базовую часть. (Но на практике композиционный подход может быть более гибким и рекомендуемым (например, this page)).

program main 
    implicit none 

    type simbase_t !! includes all non-pointer data 
     integer :: n = 0 
     real :: x = 0.0 
    endtype 

    type, extends(simbase_t) :: sim_t !! for additional pointer data 
     integer, pointer :: p => null() 
    endtype 

    type(sim_t) :: sim1, sim2 

    sim1 % n = 100 
    sim1 % x = 1.23 

    print *, "sim2 (before) = ", sim2 % simbase_t 

    write(100) sim1 % simbase_t 
    rewind(100) 
    read(100) sim2 % simbase_t 

    print *, "sim2 (after) = ", sim2 % simbase_t  
end program 

Результат:

sim2 (before) =   0 0.0000000  
sim2 (after) =   100 1.2300000 
+0

Можно даже (и в ответ IanH в), определенные пользователем I/O, так что 'записи (100) sim1' работает точно так же, как и ожидалось (с процедурами, просто делает 'write (unit, ...) obj% simbase_t'. – francescalus

+0

Спасибо за ответы. Я думаю, что разделение элементов указателя и не указателя внутри обертки, вероятно, будет таким, каким мне придется идти. – nakb

 Смежные вопросы

  • Нет связанных вопросов^_^