在 Fortran 2008 中使用非多态过程重载延迟过程
Overload deferred procedure with non-polymorphic procedure in Fortran 2008
是否可以使用非多态过程重载延迟过程?
我想创建一个带有过程 (foo
) 的抽象 class (Parent
),每个 class 都必须重载该过程 Parent
。当我想再次扩展时,我 运行 遇到了问题,例如 class (Grandchild
) 扩展了 class (Child
) 扩展了 Parent
.
由于 Child 不是抽象的,它的 foo (foo_Child
) 必须是多态的。但是后来Grandchild
继承了foo_Child
,而不是被迫定义foo_Grandchild
。此外,由于我不希望 foo_Child
是多态的,所以我希望能够在 foo_Child
.
中使用 Child
特定的非多态函数
module test_module
type, abstract :: Parent
contains
procedure(foo_Parent), deferred :: foo
end type
abstract interface
subroutine foo_Parent(this,input)
import Parent
class(Parent), intent(out) :: this
character(*), intent(in) :: input
end subroutine
end interface
type, extends(Parent) :: Child
contains
procedure :: foo => foo_Child
end type
type, extends(Child) :: Grandchild
! Is not required to define foo=>foo_Grandchild.
! This is not the behaviour I want.
end type
interface Child
module procedure new_Child
end interface
contains
function new_Child(input) result(this)
character(*), intent(in) :: input
type(Child) :: this
end function
subroutine foo_Child(this,input)
type(Child), intent(out) :: this ! Fails: 'this' is not polymorphic.
character(*), intent(in) :: input
this = Child(input) ! Fails if type(Child) is replaced by class(Child).
end subroutine
end module
program test
use test_module
end program
总结一下:
有什么方法可以使 foo_Child
成为非多态的同时也重载 foo_Parent
?还是有一种方法可以在多态过程中调用非多态函数(至少 Child=Child
使用非多态 rhs 赋值)?如果没有,是否有解决方法?
(我不想定义 class(Child)=type(Child)
,但如果这是唯一的选择,我会定义)。
对应于过程绑定传递对象的伪参数必须始终是多态的。
内在赋值语言的规则不允许赋值给不可分配的多态对象。这是因为通常这样的赋值将是类似于切片的错误 - 您将取消定义在 rhs 的动态类型中声明但不在 lhs 的声明类型中声明的对象的位。
可以使用 SELECT TYPE 和与对象的动态类型匹配的类型保护将多态对象向下转换为非多态对象。您还可以通过参数关联愉快地切入您的心内容 - 多态实际参数可以与相同声明类型的非多态虚拟参数相关联。
可以通过使父类型抽象并延迟(或保留)绑定(正如您已经完成的那样)来强制扩展实现绑定。在您的情况下,您的层次结构中可能需要额外的类型。
Parent (abstract) --> Child (abstract) +-> RealChild (concrete)
|-> GrandChild (concrete)
上面的 Child
可能只是让 foo 绑定延迟,或者它可能为该绑定提供一个过程,然后引入 RealChild
和 GrandChild
需要的新延迟绑定实施。
是否可以使用非多态过程重载延迟过程?
我想创建一个带有过程 (foo
) 的抽象 class (Parent
),每个 class 都必须重载该过程 Parent
。当我想再次扩展时,我 运行 遇到了问题,例如 class (Grandchild
) 扩展了 class (Child
) 扩展了 Parent
.
由于 Child 不是抽象的,它的 foo (foo_Child
) 必须是多态的。但是后来Grandchild
继承了foo_Child
,而不是被迫定义foo_Grandchild
。此外,由于我不希望 foo_Child
是多态的,所以我希望能够在 foo_Child
.
Child
特定的非多态函数
module test_module
type, abstract :: Parent
contains
procedure(foo_Parent), deferred :: foo
end type
abstract interface
subroutine foo_Parent(this,input)
import Parent
class(Parent), intent(out) :: this
character(*), intent(in) :: input
end subroutine
end interface
type, extends(Parent) :: Child
contains
procedure :: foo => foo_Child
end type
type, extends(Child) :: Grandchild
! Is not required to define foo=>foo_Grandchild.
! This is not the behaviour I want.
end type
interface Child
module procedure new_Child
end interface
contains
function new_Child(input) result(this)
character(*), intent(in) :: input
type(Child) :: this
end function
subroutine foo_Child(this,input)
type(Child), intent(out) :: this ! Fails: 'this' is not polymorphic.
character(*), intent(in) :: input
this = Child(input) ! Fails if type(Child) is replaced by class(Child).
end subroutine
end module
program test
use test_module
end program
总结一下:
有什么方法可以使 foo_Child
成为非多态的同时也重载 foo_Parent
?还是有一种方法可以在多态过程中调用非多态函数(至少 Child=Child
使用非多态 rhs 赋值)?如果没有,是否有解决方法?
(我不想定义 class(Child)=type(Child)
,但如果这是唯一的选择,我会定义)。
对应于过程绑定传递对象的伪参数必须始终是多态的。
内在赋值语言的规则不允许赋值给不可分配的多态对象。这是因为通常这样的赋值将是类似于切片的错误 - 您将取消定义在 rhs 的动态类型中声明但不在 lhs 的声明类型中声明的对象的位。
可以使用 SELECT TYPE 和与对象的动态类型匹配的类型保护将多态对象向下转换为非多态对象。您还可以通过参数关联愉快地切入您的心内容 - 多态实际参数可以与相同声明类型的非多态虚拟参数相关联。
可以通过使父类型抽象并延迟(或保留)绑定(正如您已经完成的那样)来强制扩展实现绑定。在您的情况下,您的层次结构中可能需要额外的类型。
Parent (abstract) --> Child (abstract) +-> RealChild (concrete)
|-> GrandChild (concrete)
上面的 Child
可能只是让 foo 绑定延迟,或者它可能为该绑定提供一个过程,然后引入 RealChild
和 GrandChild
需要的新延迟绑定实施。