Мне нужно реализовать функцию, которая будет сериализовать (то есть сохранить в неформатированный двоичный файл) класс, содержащий массив объектов, принадлежащих к одному абстрактному классу, но принадлежащих нескольким различным унаследованным классам.
Дело в том, что этот массив передается моей функции и создается действиями пользователя.Итак, у меня нет возможности узнать о конкретных типах, которые хранятся в массиве.
Есть ли способ реализовать методы ввода-вывода для записи и чтения таким образом, чтобы автоматически записывать массив без необходимостиуказать типы его отдельных элементов?
Я написал этот код, чтобы проиллюстрировать мою ситуацию:
module m
implicit none
type :: container
class(a), allocatable :: item
end type container
type, abstract :: a
integer, public :: num
contains
procedure :: write_impl => write_a
procedure :: read_impl => read_a
generic :: write(unformatted) => write_impl
generic :: read(unformatted) => read_impl
end type a
type, extends(a) :: b
integer, public :: num2
contains
procedure :: write_impl => write_b
procedure :: read_impl => 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
class(container), allocatable :: arr(:)
integer :: i
o1 = b(1,2)
o2 = c(3)
allocate(arr(2))
arr(1) = container(o1)
arr(2) = container(o2)
! How to serialize 'arr' without specifying its elements' types?
end program mwe
Итак, есть ли способ, как сериализовать такой массив без необходимости вручную указывать, что o1
имеет тип b
, а o2
имеет тип c
?
Мне нужно иметь возможность сериализовать массив абстрактного типа a
в целом, а также читать его из двоичного файла без предварительного знания его элементов.