TypechoJoeTheme

MetMan's Blog

网站页面

Fortran面向对象

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

从Fortran 2003开始标准加强了面向对象(OOP)语法支持,通过使用模块(module)及复用派生类型关键字(type)定义Fortran的类。

Fortran主要参照C++ OOP模型进行设计,两者对比如下表所示。

C++Fortran
成员在类中定义在'type'中定义
方法在类中定义在'type'中声明interface;在module中实现
构造函数default或explicit没有
对象本身this第一个参数
对象方法引用点操作符'.’%操作符

Fortran类组织方式

  • 在模块文件定义类(module ...type ...contains ... end type ...contains ... end module)
  • type...contains...end type定义类(包括数据成员及类方法声明)
  • 实际方法定义在模块contains部分实现
  • 类方法的第一个参数是对象本身
module A
  type B
    ! data members
    integer :: c 
  contains
    procedure :: d  
  end type 
contains 
subroutine d(v) 
  class(B) :: v
  ... 
end subroutine 

end module

Fortran 类定义

Fortran中type关键字除了可用于定义派生类型,也可以用于定义类,通过在type结构中增加contains子句用于类方法的声明,而在module模块的contains中实现类方法。

module mod_a
  implicit none
  !class declar as a type with contains clause
  ! followed by procedure declaration
  !Fortran class based on type objects
  type Scalar
    !data member
    real(4) :: value
  contains
    !methods declar in contains clause
    procedure,public :: printme,scaled
  end type Scalar
contains
  !actual methods definition
  subroutine printme(me)
    implicit none
    !object itself as extra parameter
    !declar as class for polymorphism, allow extension
    class(Scalar) :: me
    print '("The value is", f7.3)',me%value
  end subroutine printme
  function scaled(me,factor)
    implicit none
    class(Scalar) :: me
    real(4) :: scaled,factor

    scaled = me%value * factor
  end function scaled
end module mod_a

注意上面方法实现中第一个参数me,这里使用class关键字声明其类型,不能使用type声明其类型,因为printme和scaled是类方法(Fortran中称为type-bound procedure),class支持多态对象哑元,即不用严格是该类,可以是继承类。

在类方法定义中传递的第一个参数是类对象本身,这很像C++中类方法中对象指针this,在调用类方法时不需要显式传递调用对象本身(call obj%method(...))。

Fortran类成员方法调用

Fortran使用%指定数据成员和方法,比如obj%value,obj%add()。而C++使用点操作符.

program main
  use mod_a
  implicit none

  type(Scalar) :: x ! declare one object
  real(4) :: y
  !intialize object and data member should not be private
  x = Scalar(-3.14)
  !object itself as first implicit parameter like this pointer in C++
  call x%printme()
  y = x%scaled(2.)
  print '(f7.3)',y
end program main

可以使用typename(value)方式进行类对象的初始化。

使用类方法调用方式不需要显式传递对象本身参数。此外,类方法也可以当做普通的模块过程进行调用,此时实参必须哑元一一对应,对象参数需要显式传入,比如

call printme(x)

操作符重载

对于类对象如果想要像内置类型使用数学操作符(比如obj3 = obj1 + obj2)那样简洁操作,可以利用interface功能定义操作符重载接口。

module PointClass
  type,public :: Point
    real(8) :: x,y
  contains
    procedure,public :: distance,add,printme
  end type Point
  interface operator(+)  ! overriding operator +
    module procedure add
  end interface operator(+)
contains
  real(8) function distance(this,that)
    implicit none
    class(Point) :: this
    class(Point) :: that

    distance = sqrt((that%x-this%x)**2 + (that%y-this%y)**2)
  end function distance
  ! return type use type() not class type
  type(Point) function add(this,that) result(total)
    implicit none
    ! parameters need to be intent(in) for operator overloading
    class(Point),intent(in) :: this
    class(Point),intent(in) :: that

    total%x = this%x + that%x
    total%y = this%y + that%y
  end function add
  subroutine printme(this)
    implicit none
    class(Point) :: this

    print*, "value is",this%x, this%y
  end subroutine printme
end module PointClass

program test
  use PointClass
  implicit none
  type(Point) :: p1,p2,sum

  p1 = point(1.d0,1.d0)
  p2 = point(4.d0,5.d0)
  print*,"Distance:",p1%distance(p2)

  ! use method of class
  sum = p1%add(p2)
  call sum%printme()

  ! operator overloading
  sum = p1 + p2
  call sum%printme()

end program test

重载接口说明语法:

  interface operator(+)
    module procedure add !实际调用过程
  end interface operator(+)

重载过程定义有限制:传入的对象哑元必须是intent(in)属性,这是可以理解的,比如加法操作不能改变操作数。

参考资料

  1. Eijkhout, Lindsey, Fortran classes and objects, 2021.
  2. Markus, Object-oriented programming - introduction, 2020.
fortranoop
朗读
赞(0)
赞赏
感谢您的支持,我会继续努力哒!
版权属于:

MetMan's Blog

本文链接:

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

评论 (0)

互动读者

标签云

最新回复

暂无回复

登录
X
用户名
密码