首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FORTRAN:数据多态

FORTRAN:数据多态
EN

Stack Overflow用户
提问于 2014-09-23 16:58:41
回答 1查看 2.4K关注 0票数 4

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

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

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

办法A:

代码语言:javascript
复制
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(无限多态可分配变量):

代码语言:javascript
复制
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

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-24 02:10:12

有几个问题。

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

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

(这个限制在Fortran 2003中并不存在,但它是在后来的Fortran 2003更正中添加的--也许您的Fortran 2003编译器供应商还没有准备好实现它。)

在Fortran 2003中,当变量被分配给(等于的左手边的东西)多态时,不允许内部赋值。为多态变量赋值的能力是Fortran 2008中添加到语言中的一个特性。

以上两种问题的解决方案都是使Square子例程类型中的类型保护语句是“是”而不是“类”。

除了眼前的问题(以下内容更主观,取决于您最终计划做什么):

  • 在第一个示例中,更典型的安排是有两个独立的非类型绑定构造函数过程,一个用于MyTypeR,另一个用于MyTypeI。然后,代数操作将是MyType父级的延迟绑定,然后扩展将适当地实现该绑定。
  • 在第二个示例中,MyType并没有真正执行一个有用的角色--您最好直接使用可分配的无限多态对象。
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26000669

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档