Flo*_*nig 1 oop fortran module
我有一个基本模块,其限定某些子程序(sub1,sub2,sub3)。然后,我想在一系列子模块中覆盖这些子例程。
我知道如何使用单独的模块和延迟类型来执行此操作,但是我决定尝试使用submodules。不幸的是,我不了解它们的用法。
这是我到目前为止的内容:
BaseModule:
module BaseModule
implicit none
interface
subroutine sub1(idx)
implicit none
integer, intent(in) :: idx
end subroutine sub1
subroutine sub2(idx)
implicit none
integer, intent(in) :: idx
end subroutine sub2
subroutine sub3(idx)
implicit none
integer, intent(in) :: idx
end subroutine sub3
end interface
end module BaseModule
Run Code Online (Sandbox Code Playgroud)
ChildModule1:
submodule (BaseModule) ChildModule1
implicit none
type :: Child1
contains
module procedure :: sub1
module procedure :: sub2
end type
contains
module subroutine sub1
print*, "Child 1 - execute 'sub1' - idx = ", idx
end subroutine sub1
module subroutine sub2
print*, "Child 1 - execute 'sub2' - idx = ", idx
end subroutine sub2
end submodule ChildModule1
Run Code Online (Sandbox Code Playgroud)
ChildModule2:
submodule (BaseModule) ChildModule2
implicit none
type :: Child2
contains
module procedure :: sub1
module procedure :: sub2
module procedure :: sub3
end type
contains
module subroutine sub1
print*, "Child 2 - execute 'sub1' - idx = ", idx
end subroutine sub1
module subroutine sub2
print*, "Child 2 - execute 'sub2' - idx = ", idx
end subroutine sub2
module subroutine sub3
print*, "Child 2 - execute 'sub3' - idx = ", idx
end subroutine sub3
end submodule ChildModule2
Run Code Online (Sandbox Code Playgroud)
测试:
program test
use ChildModule1
use Childmodule2
implicit none
integer :: idx
type(Child1) :: c1
type(Child2) :: c2
do idx = 1, 10
!! Child1 outputs
call c1%sub1(idx)
call c1%sub2(idx)
!! Child2 outputs
call c1%sub1(idx)
call c2%sub2(idx)
call c1%sub3(idx)
end do
end program test
Run Code Online (Sandbox Code Playgroud)
我对子模块的了解是,我不必再次声明所有inouts,但是如果我想sub1在声明不同类型的更多子模块中使用相同的子例程(例如),该怎么办?现在我得到编译错误:
Error: MODULE PROCEDURE at (1) must be in a generic module interface
我将尝试消除一些我认为对Fortran 子模块机制有的误解。
然后,我想在一系列子模块中覆盖这些子例程。
您不使用子模块覆盖过程,而是实现它们。
我对子模块的想法是,我不必再次声明所有inout,
如果用inouts表示过程的声明和签名(接口),则是,您不需要(但可以)在子模块中重复它们,但是不,这不是子模块的目的。
但是,如果我想
sub1在声明不同类型的更多子模块中使用相同的子例程(例如),该怎么办?
好吧,也许我必须简要解释一下什么是子模块,什么不是。有关更多详细信息,请参考@SteveLionel撰写的这篇好文章,或参考 Fortran Wiki上的此项,或者参考编译器的引用(无论如何),甚至参考您最喜欢的有关Modern Fortran的书。
就像我在另一个问题中所说的那样,子模块是语言中添加的一项功能,用于解决一个特定的问题:接口和实现的分离。主要动机是当您仅需要更改模块中的实现细节时生成的编译级联。
子模块可以通过主机关联访问父模块上的实体,但是父模块不知道此子模块的存在。当您Child1在子模块中声明类型时ChildModule1,只能在该子模块本身中访问它,而不能在父模块中访问它BaseModule。
而且,ChildModule1 它不是模块,也不能use像您想做的那样在主程序或任何其他程序单元中被执行。子模块的唯一作用是实现module procedures其父模块中缺少实现的实现。
总结:以模块化,合理的方式布局源文件和程序单元,并在需要使程序实现独立于其声明(类似于c标头和源文件等)的情况下使用子模块。用一粒盐)。
编辑:
我想到您可能正在考虑,module并且submodule在Fortran中与其他语言的类和子类相关。他们不!我不知道这也许是一个普遍的误解。
Fortran具有用户定义的类型。它们可以绑定方法,构造函数和析构函数,可以封装数据,可以扩展,可以动态分派,可以声明为抽象,可以延迟和重写成员。这等效于其他语言的类。您可以(这是一种很好的做法),将每种类型和相关的内容分为相应的模块。同样,如果需要,可以为每种扩展类型都有一个模块。
但是,再次,子模块与此无关。