【问题标题】:Polymorphism in fortranfortran中的多态性
【发布时间】:2019-04-24 14:03:34
【问题描述】:

我的代码类似于:

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 、 type(Ao)、intent(in) :: Ao 的哪个位置应该这样保留,或者改为具有 class(Ao)、intent(in) :: Ao。我知道 class(Ao) 正在使变量多态并访问 A 的数据类型。但我不知道何时必须使用它。

谢谢。

【问题讨论】:

    标签: class oop polymorphism fortran2003 fortran2008


    【解决方案1】:

    如果您希望能够将函数/子例程绑定到派生类型(并且该例程能够访问/修改该类型实例的成员,这是通常的用例;参考作为“PASSing”变量),需要满足以下条件:

    • TYPE 定义必须包含适当的PROCEDURE 行(明确声明PASS,或者在未指定NOPASS 时默认存在)。
    • 函数/子例程至少有一个相关TYPE 的虚拟参数,必须在参数列表中用CLASS 声明(受所有相关限制)。
      • 它需要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 ATYPE AO 是在您尚未提供的CLASS_A 模块中定义的。我在我的版本中声明了一个虚拟类型。

    如果您想使用 NOPASS 等,事情可能会变得更复杂,但对于“正常”使用,我希望这能回答您的问题。

    【讨论】:

      猜你喜欢
      • 2015-09-22
      • 2015-02-21
      • 1970-01-01
      • 2013-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-17
      • 1970-01-01
      相关资源
      最近更新 更多