Próbuję zrozumieć różnicę między abstrakcyjnymi interfejsami a "normalnymi" interfejsami. Co sprawia, że interfejs jest abstrakcyjny? Kiedy każdy jest potrzebny?Fortran - Różnice między interfejsami ogólnymi i specyficznymi
Załóżmy przykłady poniżej
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
Wyjście jest
5.000000
2.000000
2.000000
Nie używałem abstrakcyjnych interfejsów tutaj. Przynajmniej myślę, że nie miałem? Robiłem to przez jakiś czas i nigdy nie użyłem abstrakcyjnego "kwalifikatora" na interfejsach. Wygląda na to, że nie znalazłem przypadku, w którym wymagane jest używanie abstrakcyjnych interfejsów.
Czy ktoś mógłby mnie oświecić?
PS: Kompilator Intel wizualna Fortran Composer XE 2013 z dodatkiem SP1 3.
Edit:
Cytowanie Metcalf, Reid i Cohen w Modern Fortran Poradnik:
W Fortran 95, aby zgłosić fikcyjną lub zewnętrzną procedurę z jawnym interfejsem , należy użyć bloku interfejsu. To jest w porządku dla pojedynczej procedury, ale jest nieco gęste dla deklarowania kilku procedur , które mają ten sam interfejs (oprócz nazw procedur ). Ponadto, w Fortran 2003, istnieje kilka sytuacji, w których jest to niemożliwe , gdy jest to niemożliwe (elementy wskaźnika procedury lub procedury związane z typem abstrakcyjnym ).
Czy mój kompilator błędnie akceptuje poniższy kod, a także powyższy typ abstrakcyjny?
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
W obu przypadkach powiedziałbym, że faktycznie zadeklarowałem abstrakcyjne interfejsy bez użycia abstrakcyjnego słowa kluczowego. Myślę, że moje zamieszanie ma korzenie w tym, że kompilator akceptuje kod taki jak ten.
Dziękuję, Władimir. Przykład, który przysporzył mi więcej kłopotów, jest naprawdę tym, który zawiera typy abstrakcyjne. Koncepcyjnie, powiedziałbym, że interfejsy, które deklaruję, są abstrakcyjne, ale nigdy nie musiałem ich deklarować jako takich. To doprowadziło mnie do wniosku, że naprawdę nie wiedziałem, co to jest. Teraz o wskaźnikach procedur i argumentach atrapa procedury. Nie deklaruję też dla nich abstrakcyjnych interfejsów. Czy możesz podać przykład, który po prostu nie zadziała, jeśli nie ogłoszę abstrakcyjnego interfejsu? (Z wyjątkiem tego, o którym już powiedziałeś, że kompilator może odrzucić powyższe.) – booNlatoT
Nigdy nie potrzebujesz ściśle abstrakcyjnych interfejsów. Zawsze możesz stworzyć fikcyjną procedurę i wskazać ją w procedurze() '. Dlatego abstrakcyjny interfejs jest głównie dla wygody użytkownika i dla kompletności języka. –
Edytowałem mój oryginalny wpis. Czy możesz rzucić na to okiem i powiedzieć, czy mój wniosek jest właściwy, czy nie? Ponadto, kiedy mówisz "utwórz procedurę pozorowaną", czy chcesz zgłosić jakąś procedurę pośredniczącą, której jawny interfejs będzie używany? Dziękuję ponownie. – booNlatoT