gpt4 book ai didi

polymorphism - FORTRAN:数据多态

转载 作者:行者123 更新时间:2023-12-01 11:36:56 30 4
gpt4 key购买 nike

我试图隐藏真实数据类型和复杂数据类型之间的区别。在 FORTRAN 2003 中,我认为可能有办法做到这一点。

目标是定义一个多态可分配数组,其类型可以在运行时决定。另外,还有一个子程序可以用多态数组来做一些代数(同样的方程适用于真实和复杂的数据)。

为了做到这一点,我做了两次尝试:

方法一:

module poly
implicit none
private
type, abstract, public :: MyType
contains
procedure, public :: Constructor
endtype MyType

type, extends(MyType), public :: MyTypeR
real(8), allocatable :: AllData(:)
endtype MyTypeR

type, extends(MyType), public :: MyTypeI
complex(8), allocatable :: AllData(:)
endtype MyTypeI

contains

subroutine Constructor(this, Nsize)
class(MyType), intent(inout) :: this
integer, intent(in) :: Nsize
select type(this)
type is(MyTypeR)
allocate(this%AllData(Nsize))
type is(MyTypeI)
allocate(this%AllData(Nsize))
endselect
endsubroutine
endmodule poly

! Algebra subroutine
module Operation
contains
subroutine Square(Array)
class(*), intent(inout) :: Array(:)
select type(Array)
class is(real(8))
Array = Array**2
class is(complex(8))
Array = Array**2
endselect
endsubroutine Square
endmodule Operation

! Main
program test
use poly
use Operation
class(MyType), allocatable :: t1, t2
integer :: i
logical :: IfComplex = .true.

if(IfComplex) then
allocate(MyTypeI::t1)
else
allocate(MyTypeR::t1)
endif
call t1%Constructor(4)
call Square(t1%AllData)
endprogram test

方法 B(无限多态可分配变量):
module poly
implicit none
private
type, public :: MyType
class(*), allocatable :: AllData(:)
contains
procedure, public :: Constructor
endtype MyType

contains

subroutine Constructor(this, Nsize, IfComplex)
class(MyType), intent(inout) :: this
integer, intent(in) :: Nsize
logical, intent(in) :: IfComplex
if(IfComplex) then
allocate(complex(8)::this%AllData(Nsize))
else
allocate(real(8)::this%AllData(Nsize))
endif
endsubroutine
endmodule poly

! Same algebra subroutine
! Main
program test
use poly
use Operation
type(MyType) :: t1, t2
integer :: i
call t1%Constructor(4, .true.)
call Square(t1%AllData)
endprogram test

然后我在这两种方法中的代数子例程都有问题:在内在赋值语句中,变量不应是多态的。任何建议将不胜感激。

最佳答案

有几个问题。

在当前的 Fortran 中,您不能扩展内在类型 - 内在类型不能出现在派生类型定义的 EXTENDS 说明符中。

因此,在 Fortran 2008 中,该语言禁止在选择类型构造中假装内在类型可以是祖先类型。这种禁止隐含在类型保护语句的语法规则中(TYPE IS...CLASS IS 等 - type-guard-stmt 的 CLASS IS 形式明确限制为派生类型规范,它不包括使用内在类型名称),这意味着符合 Fortran 2008 的编译器应该针对您的语法发出错误消息。

(该限制在发布的 Fortran 2003 中不存在,但在后来的 Fortran 2003 勘误中添加了 - 也许您的 Fortran 2003 编译器供应商还没有开始实现它。)

在 Fortran 2003 中,当分配给的变量(等号左侧的东西)是多态的时,不允许内部分配。分配给多态变量的能力是 Fortran 2008 语言中添加的一项功能。

解决上述两个问题的方法是在 Square 中添加类型保护语句。子程序 TYPE IS 而不是 CLASS IS。

除了那个直接的问题(以下是更主观的,取决于你最终打算做什么):

  • 在第一个示例中,更典型的安排是有两个单独的非类型绑定(bind)构造函数过程,一个用于 MyTypeR,一个用于 MyTypeI。然后,代数运算将是 MyType 父级的延迟绑定(bind),然后扩展适本地实现它。
  • 第二个示例中的 MyType 并没有真正发挥有用的作用——您还不如直接使用可分配的无限多态对象。
  • 关于polymorphism - FORTRAN:数据多态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26000669/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com