【问题标题】:Unformatted read/write of derived types containing pointers包含指针的派生类型的未格式化读/写
【发布时间】:2017-01-23 18:16:24
【问题描述】:

使用 Fortran 95。

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

最简单的就是

write(lun) myComplexType

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

因为派生类型的结构容易改变,我想避免在主代码或定义的输出过程中分别编写每个元素。

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

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

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

【问题讨论】:

    标签: pointers serialization fortran


    【解决方案1】:

    一种方法是将非指针组件拆分为它们自己的类型,然后将其用作另一个“包装器”类型的组件的类型,该类型也包含指针。

    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
    

    过程通常对包装类型的对象进行操作,这仍然将“整个状态”保持在一个结构中。

    是否合适取决于从现有类型中提取指针组件的难易程度。

    【讨论】:

      【解决方案2】:

      受 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
      

      【讨论】:

      • 甚至可以(在 IanH 的回答中)具有用户定义的 I/O,以便 write(100) sim1 完全按预期工作(过程只是在执行 write(unit,...) obj%simbase_t
      • 感谢您的回复。我认为在包装器中分离指针和非指针元素可能是我必须采用的方式。
      猜你喜欢
      • 1970-01-01
      • 2016-12-17
      • 2015-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-20
      • 2011-07-27
      • 1970-01-01
      相关资源
      最近更新 更多