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



考虑以下类型

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类一个initialise子程序,它通过首先调用deferredhelper子程序来初始化对象,然后调用sanity_check

base类看起来像:

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

每个子类将重载helper,initialise子程序将根据需要自动调用sanity_check

子类看起来像:

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对象,例如:

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

如果您愿意,您可以通过编写调用initialise的瘦包装器来重新引入foo = concrete(args)语法,尽管这可能比手动编写构造函数要做更多的工作。

相关内容

  • 没有找到相关文章

最新更新