如何覆盖用户定义的I / O程序?

时间:2018-06-07 09:13:32

标签: class fortran override method-overriding fortran2008

我有一个抽象类,我的读/写方法用于未格式化的二进制流。我还有一些继承自抽象的类,其中一些还有我想要序列化的其他组件。

所以,我希望第一组方法充当“默认”行为,并且在继承类中覆盖它的方法只能由那些特定类使用。

我试图像这样实现它:

module m
    implicit none

    type, abstract :: a
        integer, public :: num
    contains
        procedure :: write_a
        procedure :: read_a

        generic            :: write(unformatted) => write_a
        generic            :: read(unformatted)  => read_a
    end type a

    type, extends(a) :: b
        integer, public :: num2
    contains
        procedure :: write_b
        procedure :: read_b

        generic :: write(unformatted) => write_b
        generic :: read(unformatted) => read_b
   end type b

    type, extends(a) :: c
    end type c

contains

    subroutine write_a(this, unit, iostat, iomsg)
        class(a), intent(in)    :: this
        integer, intent(in)         :: unit
        integer, intent(out)        :: iostat
        character(*), intent(inout) :: iomsg

        write(unit, iostat=iostat, iomsg=iomsg) this%num
    end subroutine write_a

    subroutine read_a(this, unit, iostat, iomsg)
        class(a), intent(inout) :: this
        integer, intent(in)         :: unit
        integer, intent(out)        :: iostat
        character(*), intent(inout) :: iomsg

        read(unit, iostat=iostat, iomsg=iomsg) this%num
    end subroutine read_a

    subroutine write_b(this, unit, iostat, iomsg)
        class(b), intent(in)    :: this
        integer, intent(in)         :: unit
        integer, intent(out)        :: iostat
        character(*), intent(inout) :: iomsg

        write(unit, iostat=iostat, iomsg=iomsg) this%num, this%num2
    end subroutine write_b

    subroutine read_b(this, unit, iostat, iomsg)
        class(b), intent(inout) :: this
        integer, intent(in)         :: unit
        integer, intent(out)        :: iostat
        character(*), intent(inout) :: iomsg

        read(unit, iostat=iostat, iomsg=iomsg) this%num, this%num2
    end subroutine read_b
end module m

program mwe
    use m

    implicit none

    class(a), allocatable :: o1, o2, o3

    o1 = b(1,2)
    o2 = c(3)

    open(123, file='test5.dat', form='unformatted')
        write(123) o1
    close(123)

    allocate(b :: o3)

    open(123, file='test5.dat', form='unformatted')
        read(123) o3
    close(123)

    write(*,*) o3%num, o3%num2
end program mwe

但是我收到了以下错误:

test5.f90(29): error #8638: The type/rank signature for arguments of this specific subroutine is identical to another specific subroutine that shares the same defined I/O.   [WRITE_A]
    subroutine write_a(this, unit, iostat, iomsg)
---------------^
test5.f90(86): error #6460: This is not a field name that is defined in the encompassing structure.   [NUM2]
    write(*,*) o3%num, o3%num2
--------------------------^

对我而言似乎无法覆盖类write中的a方法。我该如何正确实施?

1 个答案:

答案 0 :(得分:2)

这不是一个完全与定义的输入/输出过程有关的问题,而是更广泛的泛型绑定和类型绑定过程。

您的类型b具有类型绑定过程,就好像(通过扩展名)它被定义为

type b
  integer, public :: num, num2
 contains
    procedure :: write_a, write_b
    procedure :: read_a, read_b
    generic   :: write(unformatted) => write_a, write_b
    generic   :: read(unformatted)  => read_a, read_n
end type

绑定write_awrite_b确实不明确(read_aread_b)。 [关于其他地方的更多细节。]

你真的不需要那些write_aread_a绑定,所以应该覆盖它们:

type, abstract :: a
    integer, public :: num
 contains
    procedure :: write => write_a
    procedure :: read => read_a

    generic   :: write(unformatted) => write
    generic   :: read(unformatted)  => read
end type a

type, extends(a) :: b
    integer, public :: num2
 contains
    procedure :: write => write_b
    procedure :: read => read_b
end type b

此处,write类型的readb绑定会覆盖a类型的绑定。 write(unformatted)read(unformatted)的通用绑定保留了b中(现在被覆盖的)绑定的映射。

相关问题