我正在用fortran學習oop。
這是我的代碼,輸出讓我吃驚:
module my_module
implicit none
type basic_t
real :: basic
end type basic_t
type, extends(basic_t) :: extended_t
real :: extended
end type extended_t
interface print_type
module procedure print_basic_type
module procedure print_extended_type
end interface print_type
contains
subroutine print_basic_type(basic)
type(basic_t), intent(in) :: basic
print *, 'in sub : print_basic_type'
end subroutine print_basic_type
subroutine print_extended_type(extended)
type(extended_t), intent(in) :: extended
print *, 'in sub : print_extended_type'
end subroutine print_extended_type
subroutine print_using_class(basic_or_extended)
class(basic_t), intent(in) :: basic_or_extended
select type (basic_or_extended)
type is (basic_t)
print *, 'the type is basic'
type is (extended_t)
print *, 'the type is extended'
end select
call print_type(basic_or_extended)
end subroutine print_using_class
end module my_module
program main
use my_module
type(basic_t) :: basic
type(extended_t) :: extended
call print_type(basic)
call print_type(extended)
print *,'------'
call print_using_class(basic)
print *,'------'
call print_using_class(extended)
end program main
這是輸出:
in sub : print_basic_type
in sub : print_extended_type
------
the type is basic
in sub : print_basic_type
------
the type is extended
in sub : print_basic_type
當我直接使用界面時print_type,它可以作業。但是當我呼叫 subroutine 時print_using_class,它??不適用于擴展型別,盡管該型別被很好地識別(參見在 subroutine 中呼叫select type之前)。是預期的輸出嗎?為什么?print_typeprint_using_class
感謝您的回答。
編輯 1
正如評論中所建議的,我應該使用“系結”。經過多次嘗試,這是我的新代碼。
module my_module
implicit none
type, abstract :: abstract_t
contains
procedure(print_abstract_t), deferred :: print_sub
end type abstract_t
abstract interface
subroutine print_abstract_t(this)
import abstract_t
class(abstract_t), intent(in) :: this
end subroutine print_abstract_t
end interface
type, extends(abstract_t) :: basic_t
real :: basic
contains
procedure :: print_sub => print_basic_type
end type basic_t
type, extends(basic_t) :: extended_t
real :: extended
contains
procedure :: print_sub => print_extended_type
end type extended_t
contains
subroutine print_basic_type(this)
class(basic_t), intent(in) :: this
print *, 'in sub : print_basic_type'
end subroutine print_basic_type
subroutine print_extended_type(this)
class(extended_t), intent(in) :: this
print *, 'in sub : print_extended_type'
end subroutine print_extended_type
subroutine print_using_class(basic_or_extended)
class(basic_t), intent(in) :: basic_or_extended
select type (basic_or_extended)
type is (basic_t)
print *, 'the type is basic'
type is (extended_t)
print *, 'the type is extended'
end select
call basic_or_extended%print_sub()
end subroutine print_using_class
end module my_module
program main
use my_module
type(basic_t) :: basic
type(extended_t) :: extended
call basic%print_sub()
call extended%print_sub()
print *,'------'
call print_using_class(basic)
print *,'------'
call print_using_class(extended)
end program main
我很驚訝,但它有效。當我在 fortran 中學習 OOP 時,任何批評都將不勝感激。
uj5u.com熱心網友回復:
在子例程print_using_class中有對print_type帶有實際引數的泛型的參考basic_or_extended。
泛型print_type有兩個特定的介面,print_basic_type和print_extended_type. (因為這些特定程序使用非多型引數,所以它們沒有歧義(Fortran 2018, 15.4.3.4.5)。)在對泛型的參考中,我們需要決議對特定程序的參考。(F2018, 15.5.5.2)
參考這兩個特定程序中的哪一個的決議不是基于動態型別;解析度基于宣告的型別。
為什么?
相關的虛擬引數是:
type(basic_t)在print_basic_typetype(extended_t)在print_extended_type
參考的特定程序是虛擬引數與class(basic_or_extended)(F2018, 15.5.2.4) 型別兼容的程序。(回想一下,只有一個特定的可以始終如一地參考。)
type(basic_t)與class(basic_t);型別兼容 type(extended_t)不是(F2018,7.3.2.3 p.5)。對泛型的參考print_type始終是 to print_basic_type。(注意 aclass(basic_t)與 a 型別兼容,type(extended_t)但我們需要 dummy 與實際型別兼容,而不是實際與 dummy 型別兼容:型別兼容性不是對稱的。)
如果您想使用泛型并決議實際引數的動態型別,那么您不能。您可以做的是擁有另一個所需宣告型別的物件:
subroutine print_using_class(basic_or_extended)
class(basic_t), intent(in) :: basic_or_extended
select type (basic_or_extended)
type is (basic_t)
print *, 'the type is basic'
call print_type(basic_or_extended)
type is (extended_t)
print *, 'the type is extended'
call print_type(basic_or_extended)
end select
end subroutine print_using_class
但理想情況下,您不會這樣做。取而代之的是,您將使用系結和型別系結的程序,而這種動態解決方案剛剛失效。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/489518.html
