1

鉴于下面的最小工作示例,我想对其进行修改以避免复制/粘贴

call func_some_calc1(par)
call func_some_calc2(par)

main_func_problem1main_func_problem2中。理想情况下,我希望有一个函数main_func对类型t_parameters_problem1t_parameters_problem2. 我可以将其par参数声明为 base type class(t_parameters_base),但是根据实际参数类型(使用select type)在该函数内部进行开关在架构上并不好。

为了解决这个问题,我尝试创建一个procedurein type t_parameters_base,它正在调用这些例程,以实现类似这样的东西(C++ 语法):

class t_parameters_base {
  virtual void main_func() {
    func_some_calc1(this)
    func_some_calc2(this)
  }
}
class t_parameters_problem1: public t_parameters_base {
  virtual void main_func() {
    t_parameters_base::main_func();
    func_some_calc3_problem1(this);
  }
}

但问题是这些例程正在使用这种类型的输入参数,这会导致循环依赖。如何解决这个问题?

更新:请注意,我真的想保留不同文件(模数/类)的实现func_some_calc1func_some_calc2因为它们使用类中的一些私有函数实现了非常不同的逻辑。

module parameters_base
  type, public :: t_parameters_base
    integer :: n
  end type t_parameters_base
end module parameters_base

module parameters_problem1
  use parameters_base
  implicit none

  type, extends(t_parameters_base), public :: t_parameters_problem1
    integer :: p1
  end type t_parameters_problem1
end module parameters_problem1

module parameters_problem2
  use parameters_base
  implicit none

  type, extends(t_parameters_base), public :: t_parameters_problem2
    integer :: p2
  end type t_parameters_problem2
end module parameters_problem2

module some_calc1
  use parameters_base
  implicit none
contains
  subroutine func_some_calc1(par)
    class(t_parameters_base) :: par
  end subroutine func_some_calc1
end module some_calc1

module some_calc2
  use parameters_base
  implicit none
contains
  subroutine func_some_calc2(par)
    class(t_parameters_base) :: par
  end subroutine func_some_calc2
end module some_calc2

module some_calc3_problem1
  use parameters_problem1
  implicit none
contains
  subroutine func_some_calc3_problem1(par)
    type(t_parameters_problem1) :: par
    print*, par%p1
  end subroutine func_some_calc3_problem1
end module some_calc3_problem1

module some_calc3_problem2
  use parameters_problem2
  implicit none
contains
  subroutine func_some_calc3_problem2(par)
    type(t_parameters_problem2) :: par
    print*, par%p2
  end subroutine func_some_calc3_problem2
end module some_calc3_problem2

module main_problem1
  use parameters_problem1
  use some_calc1
  use some_calc2
  use some_calc3_problem1
  implicit none
contains
  subroutine main_func_problem1(par)
    type(t_parameters_problem1) :: par

    call func_some_calc1(par)
    call func_some_calc2(par)
    call func_some_calc3_problem1(par)
  end subroutine main_func_problem1
end module main_problem1

module main_problem2
  use parameters_problem2
  use some_calc1
  use some_calc2
  use some_calc3_problem2
  implicit none
contains
  subroutine main_func_problem2(par)
    type(t_parameters_problem2) :: par

    call func_some_calc1(par)
    call func_some_calc2(par)
    call func_some_calc3_problem2(par)
  end subroutine main_func_problem2
end module main_problem2

program module_test
  use parameters_problem1
  use parameters_problem2
  use main_problem1
  use main_problem2

  implicit none

  type(t_parameters_problem1) :: par1
  type(t_parameters_problem2) :: par2

  par1%p1 = 1
  par2%p2 = 2

  call main_func_problem1(par1)
  call main_func_problem2(par2)
end program module_test
4

1 回答 1

0

我认为,您的目标是具有类型绑定过程的多态类型。您可以在下面找到一个工作示例。为了简单起见,我没有向类型添加任何数据,但当然,这很容易做到。该例程invokeCalc12仅在基类型中定义,但可以从派生类型中调用,并且在 Fortran 中所有方法都是虚拟的,它将调用正确的方法。

module calc_base
  implicit none

  type, abstract :: CalcBase
  contains
    procedure(calcInterface), deferred :: calc1
    procedure(calcInterface), deferred :: calc2
    procedure :: invokeCalc12
  end type CalcBase

  interface
    subroutine calcInterface(self, ii)
      import :: CalcBase
      class(CalcBase), intent(inout) :: self
      integer, intent(in) :: ii
    end subroutine calcInterface
  end interface

contains

  subroutine invokeCalc12(self, ii)
    class(CalcBase), intent(inout) :: self
    integer, intent(in) :: ii
    call self%calc1(ii)
    call self%calc2(ii)
  end subroutine invokeCalc12

end module calc_base


module some_calc
  use calc_base
  implicit none

  type, extends(CalcBase) :: SomeCalc
  contains
    procedure :: calc1
    procedure :: calc2
    procedure :: calc3
  end type SomeCalc

contains

  subroutine calc1(self, ii)
    class(SomeCalc), intent(inout) :: self
    integer, intent(in) :: ii
    print *, "SomeCalc1:calc1", ii
  end subroutine calc1

  subroutine calc2(self, ii)
    class(SomeCalc), intent(inout) :: self
    integer, intent(in) :: ii
    print *, "SomeCalc1:calc2", ii
  end subroutine calc2

  subroutine calc3(self, ii)
    class(SomeCalc), intent(inout) :: self
    integer, intent(in) :: ii
    call self%%invokeCalc12(ii)
  end subroutine calc3

end module some_calc


program test
  use some_calc
  implicit none

  type(SomeCalc) :: mySimulation

  call mySimulation%calc3(42)

end program test

注意:我在comp.lang.fortran上看到过类似的问题,但目前我没有在那里找到工作示例,因此在此处发布。

于 2015-06-23T14:00:47.737 回答