fortran - Fortran 2008 中的非多态过程重载延迟过程

标签 fortran fortran2008

是否可以使用非多态过程重载延迟过程?

我想创建一个带有过程( Parent )的抽象类( foo ),该过程必须由扩展 Parent 的每个类重载。 。当我想再次扩展时,我遇到了问题,例如一个类( Grandchild )扩展了一个类( Child ),该类扩展了 Parent 。 .

由于 Child 不是抽象的,因此它的 foo ( foo_Child ) 必须是多态的。但后来Grandchild继承foo_Child ,而不是被迫定义 foo_Grandchild 。此外,因为我不想 foo_Child为了实现多态,我希望能够使用 Child -foo_Child内的特定非多态函数.

module test_module

  type, abstract :: Parent
  contains
    procedure(foo_Parent), deferred :: foo
  end type

  abstract interface
    subroutine foo_Parent(this,input)
      import Parent
      class(Parent), intent(out) :: this
      character(*),  intent(in)  :: input
    end subroutine
  end interface

  type, extends(Parent) :: Child
  contains
    procedure :: foo => foo_Child
  end type

  type, extends(Child) :: Grandchild
    ! Is not required to define foo=>foo_Grandchild.
    ! This is not the behaviour I want.
  end type

  interface Child
    module procedure new_Child
  end interface
contains

function new_Child(input) result(this)
  character(*), intent(in) :: input
  type(Child)              :: this
end function

subroutine foo_Child(this,input)
  type(Child),  intent(out) :: this ! Fails: 'this' is not polymorphic.
  character(*), intent(in)  :: input

  this = Child(input) ! Fails if type(Child) is replaced by class(Child).
end subroutine
end module

program test
  use test_module
end program

总结一下:

有没有办法制作foo_Child非多态但也重载 foo_Parent ?或者是否有一种方法可以在多态过程中调用非多态函数(至少 Child=Child 使用非多态 rhs 赋值)?如果没有,有解决方法吗?

(我不想定义 class(Child)=type(Child) ,但如果这是唯一的选择,我会这样做)。

最佳答案

与过程绑定(bind)的传递对象相对应的虚拟参数必须始终是多态的。

内部赋值语言的规则不允许对不可分配的多态对象进行赋值。这是因为通常这样的赋值将是类似于切片的错误 - 您将取消定义在 rhs 的动态类型中声明的对象位,而不是在 lhs 的声明类型中声明的对象位。

使用 SELECT TYPE 和与对象的动态类型匹配的类型保护,可以将多态对象向下转换为非多态对象。您还可以通过参数关联轻松切入您的内心内容 - 多态实际参数可以与相同声明类型的非多态虚拟变量相关联。

可以通过使父类型抽象并使(或保留)绑定(bind)延迟(正如您已经完成的那样)来强制扩展实现绑定(bind)。在您的情况下,可能需要在层次结构中添加额外的类型。

Parent (abstract) --> Child (abstract) +-> RealChild (concrete)
                                       |-> GrandChild (concrete)
上面的

Child 可能只是让 foo 绑定(bind)延迟,或者它可能为该绑定(bind)提供一个过程,然后引入一个新的延迟绑定(bind),RealChildGrandChild 需要实现。

关于fortran - Fortran 2008 中的非多态过程重载延迟过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50158320/

相关文章:

fortran - 大型阵列导致 OpenMP 崩溃

c - Makefile 与 Fortran 和 C 混淆

function - Fortran函数返回意外的类型和值

linux - 套接字编程 gfortran

unit-testing - 如何对接口(interface)在子模块中定义的函数进行单元测试

module - 在创建单独的模块过程时,在什么情况下您会在子模块中使用 "module procedure"?

arrays - Fortran 中是否有用于将数组初始化为零的内在函数?

c - 有没有 Fortran 编译器之类的东西?