【发布时间】:2016-07-03 19:54:31
【问题描述】:
我正在尝试设置一个 Fortran OOP 代码,其中父类型 geom 具有可分配字段 shape。该字段分配有geom 的扩展类型之一,它们是circle 或rectangle 类型。在另一个模块中,我有一个 body 类型,其中包含一个 geom 字段等。
所以基本上我想要一个 geom 类型,它实际上可以访问不同的类型(然后将根据类型访问不同的字段)和一个 body 类型,它使用几何初始化。
找到下面的代码。这是几何的模块:
module geomMod
implicit none
type :: geom
class(*),allocatable :: shape
contains
procedure,private :: set_geom
generic :: assignment(=) => set_geom
end type geom
type,extends(geom) :: circle
integer :: id=1
real :: centre(2)
real :: radius
end type circle
type,extends(geom) :: rectangle
integer :: id=2
real :: centre(2)
real :: length(2)
end type rectangle
contains
subroutine set_geom(a,b)
implicit none
class(geom),intent(inout) :: a
class(*),intent(in) :: b
allocate(a%shape,source=b)
end subroutine set_geom
end module geomMod
这是正文的模块:
module bodyMod
use geomMod
implicit none
type :: body
class(geom),allocatable :: geom1
real,allocatable :: x(:,:)
integer :: M=50
real :: eps=0.1
contains
procedure :: init
end type body
contains
subroutine init(a,geom1,M,eps)
implicit none
class(body),intent(inout) :: a
class(geom),intent(in) :: geom1
integer,intent(in),optional :: M
real,intent(in),optional :: eps
allocate(a%geom1,source=geom1)
if(present(M)) a%M = M
if(present(eps)) a%eps = eps
if(.not.allocated(a%x)) allocate(a%x(a%M,2))
end subroutine init
end module bodyMod
这就是我从主文件初始化它们的方式:
use bodyMod
implicit none
integer,parameter :: M = 500
real,parameter :: eps = 5
type(body) :: b
type(geom) :: geom1
geom1 = circle(centre=(/1,1/),radius=0.5)
call b%init(geom1=geom1,M=M,eps=eps)
但是,使用 gfortran 4.8.4 编译时出现此错误。
geom1 = circle(centre=(/1,1/),radius=0.5)
1
Error: No initializer for component 'shape' given in the structure constructor at (1)!
【问题讨论】:
-
gfortran 4.8.4。有了那个标签,我的意思是我使用 F2003 OOP 样式而不是 F90 进行编码。但我已将其删除,因为它可能会造成混淆。
-
我已经根据解决错误消息进行了回答,但我不完全确定我是否遵循您的预期设计。拥有一个扩展类型有一个继承的组件,你打算用扩展类型本身的动态类型分配它让我感到困惑。不过,我没有密切关注你之前关于这个主题的问题,所以我可能遗漏了一些东西。这就是说我打算回答有关错误的问题,而不是评论设计方面。
-
把“geom”改成一个空的基类,简单地做为“call b% init(circle( center=[1.0,1.0], radius=0.5)),不是更简单吗? M=M, eps=eps )" ? (因为“body”已经有了“class(geom), allocatable”,这似乎足以容纳几何信息。)
-
是的。我也想过将
geom作为一个空类。但我希望geom持有circle,然后使用geom初始化body。 -
是的,抱歉,应该检查两次。
标签: oop fortran derived-types type-bounds