Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran 多态元素数组中类型绑定过程的问题_Fortran - Fatal编程技术网

Fortran 多态元素数组中类型绑定过程的问题

Fortran 多态元素数组中类型绑定过程的问题,fortran,Fortran,我正在用新特性更新一些代码,理想情况下,我的解决方案将包括一个数组,其中每个元素都是不同类型的,这在fortran中是不可能的。因此,我尝试使用多态对象数组,但在初始化数组元素之后,我似乎无法调用任何类型绑定的子例程 这是问题的要点 类型声明模块: type :: fruit end type fruit type, extends(fruit) :: apples contains procedure :: init => init_apples end type apples ty

我正在用新特性更新一些代码,理想情况下,我的解决方案将包括一个数组,其中每个元素都是不同类型的,这在fortran中是不可能的。因此,我尝试使用多态对象数组,但在初始化数组元素之后,我似乎无法调用任何类型绑定的子例程

这是问题的要点

类型声明模块:

type :: fruit
end type fruit

type, extends(fruit) :: apples
contains
procedure :: init => init_apples
end type apples

type, extends(fruit) :: oranges
contains
procedure :: init => init_oranges
end type oranges

contains

pure subroutine init_apples(me)
class(apples), intent(inout) :: me

! Do Stuff

end subroutine init_appples

pure subroutine init_oranges(me)
class(oranges), intent(inout) :: me

! Do Stuff

end subroutine init_oranges

在主程序中,然后:

use apropriate module

type fruit_basket
  class(fruit), allocatable :: item
end type

type(fruit_basket), allocatable :: gift(:)

allocate(gift(2))

!Option 1
allocate(apples::gift(1).item)
allocate(oranges::gift(2).item)

!Option 2
gift(1) = fruit_basket(apples)
gift(2) = fruit_basket(oranges)
编译器接受上述任一选项。现在理想情况下,我想为其中一个元素调用init

!Tried this
call gift(1).init()

!Also tried this
call gift(1).item.init()
以下任一项都会产生错误: 错误#6460:这不是包含结构中定义的字段名。[初始化]

我做错了什么

编辑:

所以我有点让它工作了,对它的工作方式不是很满意,但我想它可以:

类型声明:

Module type_declaration

  implicit none

  type, abstract, public :: Base_Type
  contains
  procedure(init_base), deferred :: init
  procedure(get_base), deferred  :: GetResult
  end type

  interface
  pure subroutine init_base(this, x)
  import Base_Type
  class(base_type), intent(inout) :: this
  real(8), intent(in) :: x
  end subroutine

  real(8) pure function get_base(this)
  import Base_Type
  class(base_type), intent(in) :: this
  end function

  end interface

  type, extends(Base_Type) :: Subtype1
    real(8) alpha
  contains
  procedure :: init => init_type1
  procedure :: GetResult => get_res_type1
  end type

  type, extends(Base_Type) :: Subtype2
    real(8) alpha, beta
  contains
  procedure :: init => init_type2
  procedure :: GetResult => get_res_type2
  end type

  contains

  pure subroutine init_type1(this, x)
  class(Subtype1), intent(inout) :: this
  real(8), intent(in) :: x

  !Work here
  this.alpha = x * 2.

  end subroutine

  pure subroutine init_type2(this, x)
  class(Subtype2), intent(inout) :: this
  real(8), intent(in) :: x

  !Work here
  this.alpha = x * 2
  this.beta  = x / 3.

  end subroutine

  real(8) pure function get_res_type1(this)
  class(Subtype1), intent(in) :: this

  get_res_type1 = this.alpha

  end function

  real(8) pure function get_res_type2(this)
  class(Subtype2), intent(in) :: this

  get_res_type2 = this.alpha + this.beta

  end function  

  end module type_declaration
主程序变量1:

    program Polymorhic_Test

    use type_declaration

    implicit none

    type data_container
      class(Base_type), allocatable :: item
    end type

    type(data_container) :: MainArray(2)

    real(8)        :: x, y = 0.
    character(10)  :: cDummy

    allocate(Subtype1::MainArray(1).item)
    allocate(Subtype2::MainArray(2).item)

    x = 1.
    call MainArray(1).item.init(x)
    y = MainArray(1).item.GetResult()

    x = 2.
    call MainArray(2).item.init(x)
    y = MainArray(2).item.GetResult()

    read cDummy

  end program Polymorhic_Test
主程序变量2

program Polymorhic_Test

  use type_declaration

  implicit none

  type data_container
    class(Base_type), allocatable :: item
  end type

  type(data_container) :: MainArray(2)

  real(8)        :: x, y = 0.
  character(10)  :: cDummy
  type(Subtype1) :: ST1
  type(Subtype2) :: ST2

  x = 1.
  call ST1.init(x)
  allocate(MainArray(1).item, source=ST1)
  y = MainArray(1).item.GetResult()

  x = 2.
  call ST2.init(x)
  allocate(MainArray(2).item, source=ST2)
  y = MainArray(2).item.GetResult()

  read cDummy

  end program Polymorhic_Test

我可能会选择选项2,因为这样我就不必在基类型中延迟init,因为我的子类型将具有init所需的不同数量的参数,并且我不喜欢基类型init具有20个左右可选参数的想法。

您也可以使用类似于(第4节和第5节)的链表实现


但是,在您的情况下,您可能仍然无法避免使用
选择类型
语句。

礼物(1)
属于声明类型
果篮
礼物(1)%item
属于声明类型
水果
,两者都没有类型绑定过程
init
。如果你不理解这些方面,那么我们可能会发现相关的问题。例如,请参阅“弗朗西斯卡路斯”,谢谢你链接到这个问题。不幸的是,这正是我想要避免的。其想法是让扩展类型具有自己的一组(可能不重叠)子例程和参数。但是,如果我不得不推迟基本类型中的整个混乱,它会使整个不那么吸引人。我的意思是,编译器应该如何知道我指的是什么扩展类型呢。我的印象是,有一种方法可以解决这个问题。人们并不真正需要链表,这里有很多关于StackOverflow的例子,如何使用包装容器的数组。