在扩展类型的构造函数末尾自动执行抽象父类型的类型绑定过程

Automatically execute type-bound procedure of abstract parent type at the end of extended type's constructor

考虑以下类型。

TYPE, ABSTRACT:: base
...
  CONTAINS

  SUBROUTINE sanity_check
  END SUBROUTINE

END TYPE

TYPE, EXTENDS(base):: concrete1
...
END TYPE

TYPE, EXTENDS(base):: concrete2
...
END TYPE

其中...表示一些与问题无关的数据。 concrete1concrete2类型在代码中定义了构造函数,子例程sanity_check也实现了

现在,我想自动concrete1concrete2的构造函数结束时执行sanity_check。换句话说,sanity_check 应该在扩展 base 的任何类型的构造函数的末尾执行,而不需要在构造函数中显式调用它。如果其他程序员要编写扩展 base 的类型,这将很有用,以检查所有数据是否已由其扩展类型正确初始化,而无需程序员显式调用 sanity_check

这有可能吗?我已经看到可以为抽象类型定义一个接口,但我不知道它是否可以用来实现我上面描述的(或者它是否有任何用处,因为抽象类型不能根据定义实例化)。

正如 francescalus 所说,你不可能完全按照自己的意愿行事。

但是,如果您的所有构造函数都采用相同的参数,那么您可以通过将构造函数替换为初始化子例程来合理地接近您想要的结果。

您可以给 base class 一个 initialise 子例程,它通过首先调用 deferred helper 子例程来初始化 object,然后调用 sanity_check.

base class 看起来像:

module base_module
  implicit none
  
  type, abstract :: base
  contains
    procedure :: sanity_check
    procedure :: initialise
    procedure(helper_base), deferred :: helper
  end type
contains
  subroutine sanity_check(this)
    class(base), intent(in) :: this
  end subroutine
  
  subroutine initialise(this, args)
    class(base), intent(out) :: this
    integer, intent(in) :: args
    
    call this%helper(args)
    call this%sanity_check
  end subroutine
  
  abstract interface
    subroutine helper_base(this, args)
      import base
      class(base), intent(out) :: this
      integer, intent(in) :: args
    end subroutine
  end interface
end module

每个 child class 都会重载 helper,并且 initialise 子例程会根据需要自动调用 sanity_check

A child class 看起来像:

module concrete_module
  implicit none
  
  type, extends(base) :: concrete
  contains
    procedure :: helper => helper_concrete
  end type
contains
  subroutine helper_concrete(this, args)
    class(concrete), intent(out) :: this
    integer, intent(in) :: args
  end subroutine
end module

然后您将构建一个 concrete object,例如

type(concrete) :: foo
integer :: args = 1
call foo%initialise(args)

如果你愿意,你可以 re-introduce foo = concrete(args) 语法,方法是编写一个调用 initialise 的精简包装器,尽管这可能比仅手动编写构造函数需要更多工作。