есть ли более чистый способ express производного типа, кроме предложения типа select? - PullRequest
4 голосов
/ 04 августа 2020

в приведенном ниже коде я использую функции производных типов, чтобы иметь общий API для создания новых производных типов из текущих объектов. Я понимаю, что компилятор не может получить информацию о типе из операторов выделения, поскольку объект также может быть освобожден и перераспределен как что-то еще, но мне любопытно, есть ли более чистый способ работы с выделенным объектом как с надлежащим производным типом, кроме оператор выбора типа. Что-то в нем просто забавно, потому что внутри функции я абсолютно знаю, что это за тип, даже если компилятор не

module poly

  implicit none

  type, abstract :: parent
   contains
     procedure(i_new_child), deferred, pass(this) :: new_child
  end type parent

  interface
     function i_new_child(this) result(child)
       import
       class(parent), intent(in) :: this
       class(parent), allocatable :: child
     end function i_new_child
  end interface

  type, extends(parent) :: child1
     integer :: a
   contains
     procedure, pass(this) :: new_child => new_child1
  end type child1

contains

  function new_child1(this) result(child)
    class(child1), intent(in) :: this
    class(parent), allocatable :: child
    allocate(child1 :: child)
    ! child%a = 1  ! 'a' at (1) is not a member of the 'parent' structure
    select type (child)
       class is (child1)
          child%a = 1
    end select
  end function new_child1

end module poly

1 Ответ

3 голосов
/ 04 августа 2020

В случаях, когда требуется «сложная» конструкция, выделите переменную конкретного типа, а затем MOVE_ALLO C эту переменную перед результатом.

function new_child1(this) result(child)
  class(child1), intent(in) :: this
  class(parent), allocatable :: child
  type(child1), allocatable :: tmp
  
  allocate(tmp)
  tmp%a = 1
  ! Real world complex construction goes here.
  ! Once construction of tmp is complete:
  call move_alloc(tmp, child)
end function new_child1

Для тривиальной / простой конструкции используйте конструктор структуры в сочетании с автоматическим c распределением при присвоении переменной polymorphi c.

function new_child1(this) result(child)
  class(child1), intent(in) :: this
  class(parent), allocatable :: child
  
  child = child1(a=1)
end function new_child1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...