TypechoJoeTheme

MetMan's Blog

网站页面

Fortran面向对象(三)

MetMan博 主
2024-08-10
/
0 评论
/
37 阅读
/
518 个字
/
百度已收录
08/10
本文最后更新于 2024年08月10日,已超过 40天没有更新。如果文章内容或图片资源失效,请留言反馈,我会及时处理,谢谢!

继续Fortran面向对象的学习。

Unlimited polymorphic types

class(*) 类型称为无限制多态类型,必须拥有pointer或allocatable属性。括号中用*代替具体的类名表示可以是任意类。(联想C语言中void *通用指针概念)

一般不直接使用无限制多态类型,常用作过程的哑元,使用select type结构转换为指定类型使用。

CLASS(*), POINTER :: unlimited_ptr

  unlimited_ptr => base_target
  SELECT type(unlimited_ptr)
    TYPE IS (base)
    PRINT *, "base type: component value: ", unlimited_ptr%i
    TYPE IS (child)
    PRINT *, "child type: component values: ", unlimited_ptr%i,unlimited_ptr%j
  END SELECT

pass vs nopass

前面提到类方法调用时,我们不会传递第一个对象参数,因为方法调用隐含传递了。这一约定可以通过passnopass属性改变。

通过pass可以显式指定类方法的对象参数名,同时对象参数不需要放在第一个参数位置上。

  type, extends(mytype) :: mynewtype
    real :: extra
  contains
    procedure, pass(value) :: write => write_mynewtype
  end type mynewtype

  ! type-bound procedure definition
  subroutine write_mynewtype(lun, value) !对象value作为第二个参数
    integer,intent(in) :: lun
    class(mynewtype) :: value 
                 
    call value%mytype%write(lun) 
  end subroutine write_mynewtype

类方法调用与之前的完全相同。

call v%write(lun)   !完全相同 

call write_mynewtype(lun, v) ! 普通调用方法,参数顺序必须与定义一致

通过nopass指定类方法调用时不能省掉对象参数。

procedure, nopass :: write => write_mynewtype

!调用
call v%write(lun, v)

Abstract classes and deferred procedure

通过abstract定义抽象类,一般用作基类模板。其中类方法可以“延迟”(deferred)到继承类定义中实现。

我们不希望在基类实现具体的类方法,因为继承类可能还需要根据实际情况进行重置,不如只声明一个过程接口,推迟到后面继承类中实现。

首先定义一个抽象类mytemplate:

type, abstract :: mytemplate 
    ... 
contains 
    procedure(calculate_template), deferred :: calc  ! deferred keyword
end type mytemplate

mydata类继承mytemplate类,同时实现类方法clac:

type, extends(mytemplate) :: mydata
    ...
contains
    procedure(calculate_template) :: calc => calc_mydata 
end type mydata

其中procedure(calculate_template) :: calc声明语法和变量声明很相似(比如integer :: a),可以理解为:声明一个calc过程,其函数签名(参数和返回值类型)要符合calculate_template接口要求。

在上面的抽象类mytemplate定义中,延迟的类方法calc需要让编译器知道过程参数和返回值(即函数签名),因此需要通过abstract interface语法声明过程模板,描述过程的参数及返回值信息,但不会具体实现,留待后续实际过程中实现。

abstract interface
  subroutine calculate_template( t, x, y )
    import :: mytemplate
    class(mytemplate) :: t
    real :: x, y
  end subroutine calculate_template
end interface

Procedure pointers

类似于指针变量可以指向变量目标(target),Fortran标准增加了过程指针,用于指向过程(procedure)(联想C语言中的函数指针)。

! declare procedure pointer p
procedure(calculate_template), pointer :: p
! p point to subroutine my_calculation
p => my_calculation 

! call procedure 
call p( t, x, y )
call my_calculation( t, x, y )
fortranoop
朗读
赞(0)
赞赏
感谢您的支持,我会继续努力哒!
版权属于:

MetMan's Blog

本文链接:

https://blog.metman.top/index.php/archives/133/(转载时请注明本文出处及文章链接)

评论 (0)

互动读者

标签云

最新回复

暂无回复

登录
X
用户名
密码