数组无限多态指针作为虚拟变量

时间:2014-06-18 14:49:45

标签: arrays pointers polymorphism fortran

我想定义一个子程序,它在输入上有一个无限多态指针数组。 三个步骤中的简化问题(问题出现在步骤3中):

1。 对于单个指针,可以这样做:

module def

type :: type1
   real :: x
end type

type :: type2
   real(8) :: y
end type

type(type1),target :: a
type(type2),target :: b

class(*),pointer :: p

contains

subroutine printer(p)
   class(*),pointer :: p
   select type(p)
   type is (type1)
      print*,p%x
   type is (type2)
      print*,p%y
   end select
end subroutine

end module

program test
use def
a%x=3e0
b%y=5d0

p=>a
call printer(p)
p=>b
call printer(p)
end program

2。 如果我想将它推广到指针数组,我需要定义一个包含我的指针的类型并定义派生类型的数组。所以在第一步中我定义了我的类型并再次尝试了一个指针。在这里,我意识到我需要在associate构造的子程序中使用select type名称,而其余部分则直接向前延伸:

module def

type :: type1
   real :: x
end type

type :: type2
   real(8) :: y
end type

type(type1),target :: a
type(type2),target :: b

type point
   class(*),pointer :: p
end type

type(point) :: p

contains

subroutine printer(z)
   class(point) :: z
   associate (o=>z%p)
      select type(o)
      type is (type1)
         print*,o%x
      type is (type2)
         print*,o%y
      end select
   end associate
end subroutine

end module

program test
use def
a%x=3e0
b%y=5d0

p%p=>a
call printer(p)
p%p=>b
call printer(p)
end program

3。 但是,如果我现在定义所需的无限多态指针数组并相应地更改我的子程序,如下所示:

module def

type :: type1
   real :: x
end type

type :: type2
   real(8) :: y
end type

type(type1),target :: a
type(type2),target :: b

type point
   class(*),pointer :: p
end type

type(point) :: p(1:2)

contains

subroutine printer(z)
   class(point),dimension(1:) :: z
   integer :: j
   associate (o=>z%p)
   do j=1,size(z,1)
      select type(o)
      type is (type1)
         print*,o(j)%x
      type is (type2)
         print*,o(j)%y
      end select
   end do
   end associate
end subroutine

end module

program test
use def
a%x=3e0
b%y=5d0

p(1)%p=>a
p(2)%p=>b
call printer(p)
end program

我收到错误:

   associate (o=>z%p)
                 1
Error: Component to the right of a part reference with nonzero rank must not have the POINTER attribute at (1)

我理解错误,指针数组不是fortran标准的一部分。但目前我没有看到任何解决方法。如果没有这个associate构造,我就无法进行类型选择,因为这会产生错误:

      select type(z%p)
                  1
Error: Selector in SELECT TYPE at (1) is not a named variable; use associate-name=>

1 个答案:

答案 0 :(得分:3)

就这样做

subroutine printer(z)
   class(point),dimension(1:) :: z
   integer :: j
   do j=1,size(z,1)
      select type(o=>z(j)%p)
      type is (type1)
         print*,o%x
      type is (type2)
         print*,o%y
      end select
   end do
end subroutine

该关联是select type构造的一部分。

错误消息Error: Component to the right of a part reference with nonzero rank must not have the POINTER attribute at (1)的说明:不允许以a%b作为数组且aballocatable

这是因为单个pointer随机放置在内存中,而Fortran标准中的数组必须可以通过元素之间具有恒定步幅的描述符来描述。