我正试图理解抽象接口和“普通”接口之间的区别。什么使一个接口成为抽象接口?何时需要使用每种类型的接口?
假设以下是示例:
module abstract_type_mod
implicit none
type, abstract :: abstract_t
contains
procedure(abstract_foo), pass, deferred :: Foo
end type
interface
subroutine abstract_foo ( this, a, b )
import :: abstract_t
implicit none
class(abstract_t), intent(in) :: this
real, intent(in) :: a
real, intent(out) :: b
end subroutine
end interface
end module
module concrete_type_mod
use abstract_type_mod
implicit none
type, extends ( abstract_t ) :: concrete_t
contains
procedure, pass :: Foo
end type
contains
subroutine Foo ( this, a, b )
implicit none
class(concrete_t), intent(in) :: this
real, intent(in) :: a
real, intent(out) :: b
b = 2 * a
end subroutine
end module
module ifaces_mod
implicit none
interface
subroutine foo_sub ( a, b )
implicit none
real, intent(in) :: a
real, intent(out) :: b
end subroutine
end interface
end module
module subs_mod
implicit none
contains
pure subroutine module_foo ( a, b )
implicit none
real, intent(in) :: a
real, intent(out) :: b
b = 2 * a
end subroutine
end module
program test
use ifaces_mod
use subs_mod
use concrete_type_mod
implicit none
type(concrete_t) :: concrete
procedure(foo_sub) :: external_sub
procedure(foo_sub), pointer :: foo_ptr
real :: b
foo_ptr => external_sub
call foo_ptr ( 0.0, b )
print*, b
foo_ptr => module_foo
call foo_ptr ( 1.0, b )
print*, b
call concrete%Foo ( 1.0, b )
print*, b
end program
pure subroutine external_sub ( a, b )
implicit none
real, intent(in) :: a
real, intent(out) :: b
b = a + 5
end subroutine
输出结果为
5.000000
2.000000
2.000000
我在这里没有使用抽象接口。至少我认为我没有? 我已经这样做了一段时间,并且从未在接口上使用过“抽象”限定符。似乎我还没有找到需要使用抽象接口的情况。
有人能给我启示吗?
PS:编译器Intel Visual Fortran Composer XE 2013 SP1 Update 3。
编辑:
引用Metcalf,Reid和Cohen在《现代Fortran解释》中的话:
在Fortran 95中,要声明具有显式接口的虚拟或外部过程,需要使用接口块。这对于单个过程来说很好,但对于声明具有相同接口(除了过程名称)的多个过程来说有点冗长。此外,在Fortran 2003中,有几种情况会变得不可能(过程指针组件或抽象类型绑定过程)。
那么,我的编译器是否因接受以下代码以及上面带有抽象类型的代码而出错?
module ifaces_mod
implicit none
interface
subroutine foo_sub ( a, b )
implicit none
real, intent(in) :: a
real, intent(out) :: b
end subroutine
end interface
end module
module my_type_mod
use ifaces_mod
implicit none
type my_type_t
procedure(foo_sub), nopass, pointer :: Foo => null()
end type
end module
在这两种情况下,我会说我实际上已经声明了抽象接口,而没有使用抽象关键字。我认为我的困惑根源于编译器接受这样的代码。
procedure()
中指向它。因此,抽象接口主要是为了方便和语言的完整性。 - Vladimir F Героям славаfoo_sub
,且接口未声明为抽象。请注意,编译器不需要诊断此类问题,只允许其这样做。要更正您的代码,只需在单词“interface”之前添加单词“abstract”。 - Vladimir F Героям слава