fortran中的多态性 [英] Polymorphism in fortran

查看:119
本文介绍了fortran中的多态性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有类似的代码:

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的数据类型.但是我不知道什么时候必须使用它.

I am not sure where in the subroutine set_Ao , type(Ao), intent(in) :: Ao should be left like this or instead to have class(Ao), intent(in) :: Ao. I know that class(Ao) is making the variable polymorphic and accessing the data type of A. But I don't know when it has to be used one or the other.

谢谢.

推荐答案

如果您希望能够将函数/子例程绑定到派生类型(并且该例程能够访问/修改实例成员)这种类型(通常是用例;称为"PASS添加"变量),则需要满足以下条件:

If you want to be able to bind a function/subroutine to a derived type (and for that routine to be able to access/modify the members of an instance of that type, which is the usual use-case; referred to as "PASSing" a variable), you need to meet the following conditions:

  • TYPE定义必须包含相应的PROCEDURE行(可以显式声明为PASS,或者在未指定NOPASS时默认存在).
  • 函数/子例程至少有一个所讨论的TYPE的伪参数,必须在参数列表中使用CLASS声明该伪参数(受所有相关限制).
    • 需要CLASS原因,因为这可能是其他TYPE可能扩展"您的TYPE,这意味着它继承了其成员-仅当该成员有效时,例程是数据多态的.
    • The TYPE definition must contain an appropriate PROCEDURE line (either with PASS explicitly stated, or there by-default whenever NOPASS is not specified).
    • The function/subroutine have at least one dummy argument of the TYPE in question, which must be declared in the argument list with CLASS (subject to all the restrictions that entails).
      • The reason it needs CLASS for this is that some other TYPE might "extend" your TYPE, which would mean it inherits its members - this can only work if the member routines are data-polymorphic.

      我试图将您提供的代码示例修改为代表我认为您实际含义的东西,但实际上可以编译,以期希望能正确使用.

      I've attempted to modify your provided code sample into something representative of what I think you actually meant, but which actually compiles, to hopefully demonstrate correct usage.

      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模块中定义的.我已经在我的版本中声明了虚拟类型.
        • I assume your TYPE A and TYPE AO were defined in the CLASS_A module you haven't provided. I've declared a dummy type in my version.
        • 如果您想使用NOPASS等,事情可能会变得更加复杂,但是对于常规"用法,我希望这可以回答您的问题.

          Things can get more complex if you want to make use of NOPASS etc., but for "normal" usage I hope this answers your question.

          这篇关于fortran中的多态性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆