无格式读/写包含指针的派生类型

时间:2017-01-23 18:16:25

标签: pointers serialization fortran

使用Fortran 95。

我需要使用无格式写入序列化复杂的派生类型(包含其他派生类型)(随后使用未格式化的读取来重新加载它)。

最简单就是

write(lun) myComplexType

但是这不起作用,因为该类型包含指针。我并不担心保留指针(我可以单独序列化它指向的内容并在以后重新加载时重新建立指针)。

因为派生类型的结构易于更改,所以我希望避免在主代码或定义的输出过程中单独编写每个元素。

是否有一种简单的方法可以执行无格式写入,忽略指针,并且不需要我单独处理许多其他嵌套数据元素 - 这会给我一个维护问题?

如果没有一种简单的方法,我可能不得不将指针放在一个单独的并行数据结构中,但我对此并不满意,因为我需要确保它们不会分离或不同步时作为参数传递(所讨论的结构保持复杂模拟的状态,我真的希望将整个状态保持在一个结构中)。

基本目的只是将模拟状态序列化为文件间隔,以便稍后我可以从状态的序列化转储中重新启动模拟。

2 个答案:

答案 0 :(得分: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 :(得分:1)

受到Ian的回答的启发,考虑继承来分离非指针和指针数据并仅写入基本部分可能会很有趣。 (但在实践中,组合方法可能更灵活和推荐(例如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