如何覆盖用户定义的 I/O 程序?
How to override user-defined I/O procedures?
我有一个抽象 class 和我的 read/write 方法用于未格式化的二进制流。我还有一些 classes 从抽象的继承而来,其中一些有我也想序列化的附加组件。
所以,我希望第一组方法充当 "default" 行为,并且在继承的 classes 中覆盖它的方法仅供那些特定的 class 使用es.
我试过这样实现它:
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
--------------------------^
在我看来,class a
中的 write
方法无法被覆盖。我怎样才能正确实施它?
这不是完全与定义的 input/output 过程有关的问题,而是更广泛的通用绑定和类型绑定过程。
您的类型 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_a
和 write_b
确实不明确(read_a
和 read_b
也是如此)。 [有关其他地方的更多详细信息。]
您并不真正需要那些 write_a
和 read_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
此处 b
类型的 write
和 read
绑定覆盖 a
类型的绑定。 write(unformatted)
和 read(unformatted)
的通用绑定保留到 b
.
中(现在已覆盖)绑定的映射
我有一个抽象 class 和我的 read/write 方法用于未格式化的二进制流。我还有一些 classes 从抽象的继承而来,其中一些有我也想序列化的附加组件。
所以,我希望第一组方法充当 "default" 行为,并且在继承的 classes 中覆盖它的方法仅供那些特定的 class 使用es.
我试过这样实现它:
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
--------------------------^
在我看来,class a
中的 write
方法无法被覆盖。我怎样才能正确实施它?
这不是完全与定义的 input/output 过程有关的问题,而是更广泛的通用绑定和类型绑定过程。
您的类型 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_a
和 write_b
确实不明确(read_a
和 read_b
也是如此)。 [有关其他地方的更多详细信息。]
您并不真正需要那些 write_a
和 read_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
此处 b
类型的 write
和 read
绑定覆盖 a
类型的绑定。 write(unformatted)
和 read(unformatted)
的通用绑定保留到 b
.