Oop Fortran中分配和构造多态对象的规范方法是什么?
我想创建一个多态对象数组,它的构造函数根据其动态类型采用不同的伪参数。阅读了有关用户定义和结构构造函数的内容后,我认为没有办法将这些概念应用于动态分配的对象。在C++背景下,我习惯于在动态或堆栈中分配对象时可以使用同一个构造函数“成员函数”,但是如何在分配的对象上显式调用用户定义的FORTRAN构造函数? 相反,我尝试处理泛型和类型绑定的init函数:Oop Fortran中分配和构造多态对象的规范方法是什么?,oop,constructor,fortran,polymorphism,Oop,Constructor,Fortran,Polymorphism,我想创建一个多态对象数组,它的构造函数根据其动态类型采用不同的伪参数。阅读了有关用户定义和结构构造函数的内容后,我认为没有办法将这些概念应用于动态分配的对象。在C++背景下,我习惯于在动态或堆栈中分配对象时可以使用同一个构造函数“成员函数”,但是如何在分配的对象上显式调用用户定义的FORTRAN构造函数? 相反,我尝试处理泛型和类型绑定的init函数: module mod type :: basis_t contains procedure, public :: init_func =
module mod
type :: basis_t
contains
procedure, public :: init_func => init_base
! I want a generic constructor function
generic, public :: init => init_func
end type
type, extends(basis_t) :: extended_t
contains
! cannot work, init_extended has a different signature from init_base
procedure, public :: init => init_extended
end type
type wrapper_t
type(basis_t), pointer :: obj
end type
contains
subroutine init_base(this)
class(base_t), intent(inout) :: this
end subroutine
subroutine init_extended(this, param)
class(extended_t), intent(inout) :: this
integer :: param
end subroutine
end module
program
use mod
implicit none
type(wrapper_t) :: arr(2)
allocate(basis_t::arr(1)%obj)
allocate(extended_t::arr(2)%obj)
call arr(1)%obj%init ! calls init_basis
call arr(2)%obj%init(4) ! calls init_extended
end program
但是我不相信我是在正确的轨道上,比如在C++中,我宁愿做< < /P> >
basis_t* arr[2];
arr[0] = new basis_t;
arr[1] = new extended_t{ 4 };
<> P>重要区别是C++中的构造函数是<强> > < /强>类型绑定/虚,如我的FORTRAN方法。我能做什么?Fortran中构造函数的角色可以通过以下方式提供:
- 该语言提供了结构构造函数
- 一种函数,其结果属于所构造对象的类型。该语言允许泛型函数与派生类型具有相同的名称,并进一步允许对此类函数的引用重载对该类型的结构构造函数的引用
- 定义适当类型的intent(out)参数的子例程
TYPE :: ta
INTEGER :: a
END TYPE ta
TYPE, EXTENDS(ta) :: tb
REAL :: b
END TYPE :: tb
INTERFACE tb
PROCEDURE :: tb_construct
END INTERFACE tb
TYPE, EXTENDS(ta) :: tc
END TYPE tc
TYPE :: ta_item
CLASS(ta), ALLOCATABLE :: item
END TYPE ta_item
!...
FUNCTION tb_construct(arg)
INTEGER, INTENT(IN) :: arg
TYPE(tb) :: tb_construct
tb_construct%a = arg + 1
tb_construct%b = arg / 2.0
END FUNCTION tb_construct
SUBROUTINE ConstructTC(obj, arg, stat)
CLASS(ta), INTENT(OUT), ALLOCATABLE :: obj
INTEGER, INTENT(IN) :: arg
INTEGER, INTENT(OUT) :: stat
TYPE(tc), ALLOCATABLE :: tmp
IF (arg < 0) THEN
! Construction failed.
stat = 1
RETURN
END IF
tmp%a = arg + 4
CALL MOVE_ALLOC(tmp, obj)
stat = 0 ! Construction succeeded.
END SUBROUTINE ConstructTC
!...
TYPE(ta_item) :: the_items(3)
INTEGER :: stat
! Structure constructor
the_items(1)%item = ta(1)
! Overloaded function.
the_items(2)%item = tb(2)
! Subroutine.
CALL ConstructTC(the_items(3)%item, 3, stat)
IF (stat /= 0) ERROR STOP 'It failed.'
TYPE::ta
整数::a
端型ta
类型,扩展(ta)::tb
真的吗
结束类型::tb
接口tb
过程::tb_构造
终端接口tb
类型,扩展(ta)::tc
端型tc
类型::ta_项目
类(ta),可分配::项
终端类型ta_项目
!...
函数tb_构造(arg)
整数,意图(IN)::arg
类型(tb)::tb\U构造
tb_构造%a=arg+1
tb_构造%b=arg/2.0
端函数tb_构造
子例程constructC(obj、arg、stat)
类(ta)、意图(OUT)、可分配::obj
整数,意图(IN)::arg
整数,意图(输出)::stat
类型(tc),可分配::tmp
如果(arg<0),则
! 建设失败了。
stat=1
返回
如果结束
tmp%a=arg+4
呼叫移动分配(tmp、obj)
统计=0!施工成功。
结束子例程constructC
!...
类型(ta_项)::_项(3)
整数::stat
! 结构构造器
_项(1)%item=ta(1)
! 重载函数。
_项目(2)%item=tb(2)
! 子程序。
调用ConstructTC(项目(3)%item,3,stat)
如果(stat/=0)错误,请停止“它失败”
谢谢你富有启发性的回答,这正好满足了我的需要。但是,虽然我可以使用GCC的gfortran编译此代码,但英特尔编译器ifort 16.0.0(我绑定到它)将抛出诊断错误#8304:在内部赋值语句中,变量不应是多态的。[ITEM]_items(1)%ITEM=ta(1)
和错误#6197:不同结构类型的赋值无效。_items(2)%item=tb(2)
。我确信在某个时候我已经尝试过你的方法,但是偶然发现了这个问题,没有意识到这是一个编译器错误。有什么想法吗?对多态可分配函数的内在赋值是F2008的一个特性,在该版本的编译器中不可用(19.0是最新版本,20.0即将发布)。如果您使用结构构造函数或函数来构造对象,请使用ALLOCATE语句的源说明符,即ALLOCATE(the_items(1)%item,SOURCE=ta(…)