用户定义的Fortran派生类型实例的构造函数

时间:2017-10-04 17:25:40

标签: constructor fortran

这是我与Fortran相关的第二个问题(我使用C ++,请原谅我的思考方式)。

我想在适当的时候使用OOP,比如Fortran中的派生类型。 在C ++中,您可以使用用户定义的构造函数,例如https://msdn.microsoft.com/en-us/library/s16xw1a8.aspx

在Fortran中,情况有所不同。 我尝试的第一件事是从这里: https://www.ibm.com/developerworks/community/blogs/b10932b4-0edd-4e61-89f2-6e478ccba9aa/entry/object_oriented_fortran_user_defined_constructors2?lang=en

然后我找到了其他一些方法。 在这里,我列出了一些似乎可行的方法,但我只测试了第一个和第二个:

  1. 与他们应该构建的派生类型同名的通用接口,请参阅上面的链接;
  2. 使用类型绑定过程(这甚至不是“传统”构造函数)

    MODULE mymod
      TYPE mytype
        Private
        INTEGER :: x
        CONTAINS
        PROCEDURE, PASS :: init
      END TYPE
    CONTAINS
      SUBROUTINE init(this, i)
        CLASS(mytype), INTENT(OUT) :: this
        INTEGER, INTENT(IN) :: i
        write(*,*) this%x
        IF(i > 0) THEN
          this%x = 1
        ELSE
          this%x = 2
        END IF
        write(*,*) this%x
      END SUBROUTINE init
    END
    PROGRAM test
      USE mymod
      TYPE(mytype) :: y
      CALL y%init(1)
    END PROGRAM
    
  3. 使用静态构造函数或结构构造函数(http://www.lahey.com/docs/lfenthelp/NLMOvUsInvConst.htm) 但似乎这不适用于一般的Fortran http://www.lahey.com/docs/lfenthelp/NLMGSWhatIs.htm

  4. 所以我还没有完全理解在实践中初始化/构造派生类型的最优选和灵活的方法,特别是当我在开发中使用嵌套派生类型时。我希望我可以在一些帮助下组织这个主题。

1 个答案:

答案 0 :(得分:3)

好的,所以我假设你在How to override a structure constructor in fortran读了很好的答案,我会回答你在评论中提出的问题。评论中没有足够的地方回答这个问题。

您还可以在Fortran中创建接受可变数量参数的构造函数。

甚至可以使用默认结构构造函数,默认情况下每个派生类型都有。如果默认初始化组件,则它在构造函数中是可选的。对于可分配和指针组件也是如此。

对于类型

QMANAGER

您可以像

一样调用默认构造函数
type t1
  integer :: i = 1
  integer, pointer :: ip => null()
  integer, allocatable :: ap
end type

且完全合法,instance = t1() 将为1,i将指向ipnull将不会被分配。

或者您可以将其称为

ap

并且 instance = t1(ap=5) 组件将被分配并设置为5,其他组件将保留默认值。

只需创建参数ap即可实现与用户定义的构造函数类似的东西。

optional

任何类型绑定的过程当然也可以有可选的参数。

对于嵌套类型,最好将构造函数作为函数来完成,无论它们是默认的还是用户定义的:

function t1_user(ap, i) result(res)
  type(t1) :: res
  integer, allocatable :: ap !this argument MUST be passed,
                             ! it does not have to be allocated
  integer, optional    :: i ! this argument is optional

  if (present(i)) then
    ...
  end if
end function