【发布时间】:2012-07-19 07:33:50
【问题描述】:
我正在编写一个库,用于将多种类型的几何(球体、平面、NURBS 曲面、stl 文件...)导入到科学的 Fortran 代码中。这种问题似乎是为 OOP 量身定做的,因为定义 type :: geom 然后 type,extends(geom) :: analytic 等等很简单。我遇到问题的部分是文件 IO。
此时我的解决方案是编写定义形状的参数,包括一些告诉我它是哪种形状的标志。阅读时,我实例化了一个class(geom) :: object,(因为我事先不知道它将是哪个子类型)但是我该如何阅读它呢?
我无法访问该子类型的任何特定组件。我读到向下转换是verboten,此外,新的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
【问题讨论】:
-
对于我的示例代码,您的输入文件需要(至少)两条记录 - 第一条记录为类型的整数,第二条记录为球体数据。你真的得到一个段错误还是文件结束条件?
-
我在球体类型中添加了
integer :: type=1行,这只是混淆了问题。我不知道为什么这会导致段错误,但是当我按原样坚持使用您的模块时,它可以工作。谢谢! -
似乎段错误与派生类型中的任何变量都具有默认值有关。因此,如果我在类型定义中设置
radius=1,则会出现段错误。 -
您使用的是 Intel Fortran 12.x 吗?如果是这样,这听起来像是我提到的 INTENT(OUT) 多态参数的问题。具有默认初始化或可分配组件的参数基本上总是需要为 INOUT。鉴于早期的发行说明,13.0 可能会修复。
-
我正在使用 ifort -v 12.1。我可以看到默认值是如何进入数据的,所以意图应该是 INOUT。再次感谢。
标签: oop polymorphism fortran fortran2003