неограниченный полиморфный класс, указывающий на потомка (расширенный объявленный тип) в Фортране - PullRequest
0 голосов
/ 22 декабря 2018

Я пытаюсь создать структуру дерева данных с функциями, которые имитируют связанный список, используя полиморфизм в Фортране.Каждый блок или объект имеет указатель на своих потомков и один на своего родителя, оба указателя одного и того же типа объекта.Поскольку я думал о наличии ссылки на корень структуры дерева данных, я первоначально определяю объявленный тип следующим образом:

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

Я немного новичок в этом способе программирования на Фортране, поэтому я предполагаю, что что-то не полностьюЯ понимаю, я надеюсь, что вы можете придумать лучшие предложения о том, что я пытаюсь сделать.

ОБНОВЛЕНИЕ

Так что, похоже, 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)
...