实现派生类型扩展抽象类型的过程



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

如何修复我的程序?

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

  • OS: 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)

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

延迟类型绑定过程(这里是绑定move)的接口名称必须是抽象接口或具有显式接口的过程(内部过程将具有显式接口)的接口名称,但是对于该过程的位置没有额外的约束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

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

最新更新