我正在编写一个库,用于将多种类型的几何图形(球体、平面、NURBS 曲面、STL 文件...)导入到科学的 Fortran 代码中。这种问题似乎是泰勒为 OOP 设计的,因为定义一个 type::geom
,然后定义 type,extends(geom)::analytic
等等很简单。我遇到问题的部分是文件 IO。
此时我的解决方案是编写定义形状的参数,包括一些告诉我它是什么形状的标志。阅读时,我实例化一个 class(geom)::object
(因为我提前不知道它将是哪个子类型),但是我如何读取它?
我无法访问子类型的任何特定组件。我读到向下转型是禁止的,而且,新的allocate(subtype::class)
似乎不起作用。新的 READ(FORMATTED) 似乎没有由 ifort 或 gfortran 实现。即
module geom_mod
type :: geom
end type
type,extends(geom) :: sphere
integer :: type
real(8) :: center(3),radius
contains
generic :: READ(FORMATTED)=> read_sphere ! not implemented anywhere
end type
contains
subroutine read_geom(object)
class(geom),intent(out),pointer :: object
integer :: type
read(10,*) object%type ! can't access the subtype data yet
read(10,*) type
backspace(10)
if(type==1) then
allocate(sphere :: object)! downcast?
read(10,*) object ! doesn't work
end if
end read_geom
end module
我的想法是错的吗?我可以使用多态性以外的东西来破解它,但这在其他地方似乎更干净。我们将非常感谢您的帮助。
编辑:使用 IanH 模块的示例程序
program test
use geom_mod
implicit none
class(geom),allocatable :: object
open(10)
write(10,*) '1'
write(10,*) sphere(center=0,radius=1)
rewind(10)
call read(object) ! works !
end program test
最佳答案
当前的 gfortran 和 ifort 没有实现定义的输入/输出。我没有看到任何证据表明这种情况会在不久的将来发生改变。然而,除了允许一些语法快捷方式之外,该功能实际上并不能为您节省太多工作。
解决这种情况的一种方法是调用 geom 扩展的“工厂”,它使用文件中的数据将参数分配给正确的类型,然后移交给读取类型特定数据的类型绑定(bind)过程。例如:
module geom_mod
implicit none
integer, parameter :: dp = kind(1.0d0)
type, abstract :: geom
contains
procedure(read_geom), deferred :: read
end type geom
abstract interface
subroutine read_geom(object)
import :: geom
implicit none
class(geom), intent(out) :: object
end subroutine read_geom
end interface
type, extends(geom) :: sphere
real(dp) :: center(3), radius
contains
procedure :: read => read_sphere
end type sphere
contains
subroutine read(object)
class(geom), intent(out), allocatable :: object
integer :: type
read (10, *) type
! Create (and set the dynamic type of object) based on type.
select case (type)
case (1) ; allocate(sphere :: object)
case default ; stop 'Unsupported type index'
end select
call object%read
end subroutine read
subroutine read_sphere(object)
class(sphere), intent(out) :: object
read (10, *) object%center, object%radius
end subroutine read_sphere
end module geom_mod
当前的 ifort (12.1.5) 存在意图(out)多态参数的问题,可能需要解决方法,但一般方法保持不变。
(请注意,子例程读取不是类型绑定(bind)子例程 - 要读取通用几何对象,请使用传统子例程引用样式中的“call read(object)”。)
关于oop - 在 Fortran 中使用多态数据类型的文件 IO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11572318/