【发布时间】:2014-10-13 13:21:53
【问题描述】:
我以例子的形式解释我的问题。
我有一个类型 (location2d_t),其中包括两个成员 x 和 y 和一个类型绑定过程 (calcdist2d)。除了具有 (location2d_t) 类的 (this) 之外,该过程还接受其自己的类型(作为第二个虚拟参数)来计算距离。
现在,我更进一步,将类型扩展为 (location3d_t),它也具有 z。
要重新定义过程,我无法覆盖前一个过程,因此我创建了一个新过程 (calcdist3d),第二个参数类型为 (location3d_t),并创建一个通用过程 (calcdist)他们。换句话说,第二个参数有不同的类型,所以通用的想法是适用的。
在更一般的范围内,让我们在这里说主程序,为了一般性,我将我的对象声明为父类。当我分配具有子类型 (location3d_t) 的对象时,对 (calcdist) 的第二个虚拟参数为 (location3d_t) 的调用引用父泛型并表示
Error: Found no matching specific binding for the call to the GENERIC 'calcdist'
代码是
module point_mod
implicit none
type location2d_t
integer :: x,y
contains
procedure :: calcdist2d => calcdistance2d
procedure :: here => here_location2d
generic :: calcdist => calcdist2d
end type
type, extends(location2d_t) :: location3d_t
integer :: z
contains
procedure :: calcdist3d => calcdistance3d
procedure, public :: here => here_location3d
generic, public :: calcdist => calcdist3d
end type
contains
function calcdistance2d(this,location) result(output)
class(location2d_t) :: this
type(location2d_t) :: location
integer :: output
output = int(sqrt(real((location%x-this%x)**2+(location%y-this%y)**2)))
end function
function calcdistance3d(this,location) result(output)
class(location3d_t) :: this
type(location3d_t) :: location
integer :: output
output = int(sqrt(real((location%x-this%x)**2+ &
(location%y-this%y)**2+(location%z-this%z)**2)))
end function
subroutine here_location2d(this)
class (location2d_t) :: this
print*, "we are in locationd2d_t"
end subroutine
subroutine here_location3d(this)
class (location3d_t) :: this
print*, "we are in locationd3d_t"
end subroutine
end module
模块编译没有任何错误。实现以下程序以使用该模块:
program main
use point_mod
implicit none
class (location2d_t), allocatable :: loc
type (location3d_t) :: dum
allocate(location2d_t::loc)
call loc%here() ! calls location2d_t procedure
deallocate(loc)
allocate(location3d_t::loc)
call loc%here() !correctly calls procedure of location3d_t
print*,loc%calcdist(dum) ! gives error
select type (loc)
type is (location3d_t)
print*,loc%calcdist(dum) ! runs well
end select
end program
“Here”过程正确地找到了它的动态类型。为什么不显式调用子 (calcdist) 的通用过程?即使在这种明显的情况下,我是否必须始终使用“选择类型”块? 注意:我使用 GNU fortran 4.8 和 4.9 以及 ifort 14 检查了代码。
【问题讨论】:
标签: oop generics inheritance fortran