【问题标题】:Implementing a procedure of derived type extending abstract type实现派生类型扩展抽象类型的过程
【发布时间】:2021-05-17 10:23:30
【问题描述】:

我希望派生类型具有相同的行为,因此我想为抽象类定义一个接口。 所以我写了我的程序如下,但是我得到了一个编译错误。

如何修复我的程序?

PROGRAM main
  IMPLICIT NONE

  TYPE, ABSTRACT :: Point
    REAL :: x, y
  CONTAINS
    PROCEDURE(Imove), DEFERRED :: move
  END TYPE Point
  INTERFACE
    SUBROUTINE Imove(self, d)
      IMPORT Point
      CLASS(Point), INTENT(INOUT) :: self
      REAL, INTENT(IN) :: d
    END SUBROUTINE Imove
  END INTERFACE

  TYPE, EXTENDS(Point) :: Point3d
    REAL :: z
  CONTAINS
    PROCEDURE :: move => Point3d_move
  END TYPE Point3d

  TYPE(Point3d) :: p1

  p1 = Point3d(1.0, 2.0, 3.0)
  p1%move(4.0)
  PRINT *, p1%x, p1%y, p1%z

CONTAINS
  SUBROUTINE Point3d_move(self, d)
    TYPE(Point3d), INTENT(INOUT) :: self
    REAL :: d

    self%x = self%x + d
    self%y = self%y + d
    self%z = self%z + d
  END SUBROUTINE Point3d_move
END PROGRAM main

环境

  • 操作系统:macOS Catalina
  • Fortran 编译器:GNU Fortran (Homebrew GCC 10.2.0) 10.2.0
  • Error: 'point3d_move' must be a module procedure or an external procedure with an explicit interface at (1)

【问题讨论】:

  • 另外,您还没有将子例程接口声明为abstract interface
  • 我刚刚意识到这是一个程序,而不是一个模块。现在没有时间正确回答,但我 90% 确定您不能使用内部程序进行绑定。将与 Points 相关的东西放在模块中,在程序中使用。
  • 另外Point3D_move的接口与Imove不一致。
  • 'point3d_move' 必须是模块过程或外部过程使用模块,而不是内部过程
  • 我刚刚研究了 Metcalf、Reid 和 Cohen “现代 Fortran”的相关部分,我在那本书中找不到将内部子程序作为类型绑定的声明绑定程序是非标准的。但是那本书,虽然很好,但不是标准,所以我会把它留给知道那个文件的人来肯定地回答它是否被禁止。但是使用内部子程序肯定是一个非常奇怪的设计,模块会很常见,而且我有一个带有上述模块的版本,如果没有其他答案,我会发布。

标签: oop fortran fortran2003


【解决方案1】:

正如错误消息和几个 cmets 所说,要绑定的过程必须是模块过程或具有显式接口的外部过程。主程序内部的过程都不是这些。

延迟类型绑定过程(此处为绑定move)的接口名称必须是抽象接口或具有显式接口的过程(内部过程将具有)的名称,但对 where 没有额外的限制该程序可能是。1

但是,Fortran 2018 的 C769 约束是在实现时提供编译器报告Point3d_move 的错误消息。

将派生类型定义和相关实体(那些过程)移动到模块中应该是您的方法。

请注意,此约束并非特定于实现延迟绑定或扩展抽象类型。您可以在下面更简单的情况下看到完全相同的错误报告。

program main
  implicit none

  type :: Point3d
   contains
     procedure :: move
  end type Point3d

contains

  subroutine move(self)
    class(Point3d) :: self
  end subroutine move
  
end program main

在问题的情况下,延迟绑定的接口名称是具有显式接口的外部过程的名称,但使用其他无用的内部过程的名称作为接口名称同样有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-04
    • 2017-04-28
    • 1970-01-01
    • 2011-01-11
    • 2018-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多