我正在尝试使用Fortran中的多态性来构建具有模仿链接列表类型的功能的数据树结构。每个框或对象都有一个指向其子级的指针和一个指向其父级的指针,这两个指针均具有相同的对象类型。因为我想到要引用数据树结构的根,所以我最初将声明的类型定义如下:
type r_oct
integer :: max_depth
class(*), pointer :: root
end type
然后,我将其扩展为包含该数据结构主要属性的另一种类型
type, extends(r_oct) :: element_oct
rea :: pts
type(element_oct), pointer :: parent
type(element_oct), pointer :: children(:)
end type
现在我想拥有两个不同的构造函数,所以我声明以下内容
interface r_oct
module procedure :: INIT_r_oct
module procedure :: INIT_element_oct
end interface r_oct
在我的功能INIT_r_oct
中我只是拥有
function INIT_r_oct( max_depth ) result( oct )
implicit none
class(r_oct), pointer :: oct
integer, intent(in) :: max_depth
if( associated(oct) )then
print*, "ERROR, called more than once"
stop
else
allocate(oct)
nullify(oct% root)
oct% max_depth = max_depth
endif
end function INIT_r_oct
一切都很好。但是现在下面的函数是我遇到问题的地方。
这个想法是,我想保持根指针指向子对象parent
指针的第一个实例,即element_oct :: parent
function INIT_element_oct (this, pts ) result( ele_oct )
class(r_oct), pointer, intent(inout) :: this
real, intent(in) :: pts
type(element_oct), pointer :: ele_oct
allocate(ele_oct)
this%root => ele_oct
this%root%parent%pts = 1 ! this does not work
end function INIT_element_oct
它抱怨this%root
没有父属性,好像它没有达到我的预期this%root => ele_oct
对于Fortran中的这种编程方式,我有点陌生,所以我想我自己还无法完全理解某些内容,希望您能对我要做的事情提出更好的建议。
更新
因此,select type
似乎可以帮助我。
在功能INIT_element_oct
中,我改为这样做:
function INIT_element_oct (this, pts ) result( ele_oct )
class(r_oct), pointer, intent(inout) :: this
real, intent(in) :: pts
type(element_oct), pointer :: ele_oct
allocate(ele_oct)
this%root => ele_oct
select type ( aux => this% root)
type is (element_oct)
aux = ele_oct%parent ! this now works!!!
end select
end function INIT_element_oct
但是this%root
现在真的指向ele_oct%parent吗?也就是说,如果以后您想要指向第一个元素的指针,我可以使用根指针来获取,因为这似乎是临时的指向它。
是否可以使用deferred
类型解决此问题
从主程序调用
program TEST_OCT
use mod_oct
implicit none
class(r_oct), pointer :: first
class(element_oct), pointer :: octree
integer :: i,j, max_d
max_d = 10
first => r_oct(max_num_point)
oct => r_oct(first, 1.0)