Полиморфизм в Фортране - PullRequest
       66

Полиморфизм в Фортране

0 голосов
/ 22 ноября 2018

У меня есть код, подобный следующему:

Module C_sys

  use class_A

   implicit none

    Private

    Type, public :: C_sys_type

  private

   logical   :: Ao_set = .false. 

   type(A) :: Ao

 Contains

 Private

    Procedure, public :: get_Ao
    Procedure, public :: set_Ao

 End Type C_sys_type

  interface C_sys_type

   Procedure C_sys_type_constructor

  end interface C_sys_type

 Contains

type(C_sys_type) elemental function C_sys_type_constructor(Ao) result(C_sys)

   type(A), intent(in), optional :: Ao

    C_sys % Ao = Ao
   C_sys % Ao_set = .true.

end function C_sys_type_constructor

type(A) elemental function get_Ao 
  class(C_sys_type), intent(in) :: this

   get_Ao = this % Ao
 end function get_Ao

 subroutine set_Ao(this, Ao)

 class(C_sys_type), intent(inout) :: this
 type(Ao), intent(in)             :: Ao

   this % Ao     = Ao  
   this % Ao_set = .true.

end subroutine set_Ao

End Module C_sys

Я не уверен, где в подпрограмме set_Ao введите (Ao), intent (in) :: Ao, как это нужно оставить, или вместо этого, чтобы иметькласс (Ao), намерение (in) :: Ao.Я знаю, что класс (Ao) делает переменную полиморфной и получает доступ к типу данных A. Но я не знаю, когда ее нужно использовать один или другой.

Спасибо.

1 Ответ

0 голосов
/ 12 декабря 2018

Если вы хотите иметь возможность привязать функцию / подпрограмму к производному типу (и чтобы эта подпрограмма могла иметь доступ / изменять члены экземпляра этого типа, что является обычным вариантом использования;как «PASS ing» (переменная), вам необходимо выполнить следующие условия:

  • Определение TYPE должно содержать соответствующую строку PROCEDURE (либо с явно указанным PASS,или там по умолчанию всякий раз, когда NOPASS не указан).
  • Функция / подпрограмма имеют как минимум один фиктивный аргумент рассматриваемого TYPE, который должен быть объявлен в списке аргументов с помощью CLASS(с учетом всех ограничений, которые влечет за собой).
    • Причина 1016 *, в которой он нуждается CLASS, заключается в том, что некоторые другие TYPE могут «расширить» ваш TYPE, что означает, что он наследует своих членов - это может работать только в том случае, еслиподпрограммы-члены являются полиморфными данными.

Я попытался изменить предоставленный вами пример кода, чтобы он представлял то, что, на мой взгляд, вы на самом деле имели в виду, но которое фактически компилируется, чтобынадеюсь продемонстрировать правильное использование.

module c_sys
  implicit none

  private

  type, public :: a
    integer :: i
  end type

  type, public :: c_sys_type
    private
    logical :: ao_set = .false.
    type(a) :: ao
  contains
    private
    procedure, public :: get_ao
    procedure, public :: set_ao
  end type c_sys_type

  interface c_sys_type
    procedure c_sys_type_constructor
  end interface c_sys_type

contains

  type(c_sys_type) elemental function c_sys_type_constructor(ao) result(c_sys)
    type(a), intent(in), optional :: ao

    c_sys % ao = ao
    c_sys % ao_set = .true.
  end function c_sys_type_constructor

  type(a) elemental function get_ao(this)
    class(c_sys_type), intent(in) :: this

    get_ao = this % ao
  end function get_ao

  subroutine set_ao(this, ao)
    class(c_sys_type), intent(inout) :: this
    type(a),           intent(in)    :: ao

    this % ao     = ao
    this % ao_set = .true.
  end subroutine set_ao

end module c_sys
  • Я предполагаю, что ваши TYPE A и TYPE AO были определены в модуле CLASS_A, который вы не предоставили.Я объявил фиктивный тип в моей версии.

Вещи могут стать более сложными, если вы хотите использовать NOPASS и т. Д., Но для "нормального" использования я надеюсь, что это ответ на ваш вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...