Oop 如何在抽象派生类型中设计私有可重写过程?
通常,抽象类型是后代派生类型的模型。如果类型中包含的过程被延迟,则该类型中包含的过程应该是公共的,因为私有过程不能在模块本身之外被引用或重写。但是,如果我希望每个子体都有相同的函数私有过程来执行某些操作(例如,测试其实例的初始化状态),那么如何设计抽象派生类型呢?我是否必须在每个子体中手动定义它们,或者我是否可以抽象地放置一个模型并在子体中实现它? 下面是一个例子:Oop 如何在抽象派生类型中设计私有可重写过程?,oop,fortran,private,abstract,Oop,Fortran,Private,Abstract,通常,抽象类型是后代派生类型的模型。如果类型中包含的过程被延迟,则该类型中包含的过程应该是公共的,因为私有过程不能在模块本身之外被引用或重写。但是,如果我希望每个子体都有相同的函数私有过程来执行某些操作(例如,测试其实例的初始化状态),那么如何设计抽象派生类型呢?我是否必须在每个子体中手动定义它们,或者我是否可以抽象地放置一个模型并在子体中实现它? 下面是一个例子: module test1 implicit none private public :: my_nume
module test1
implicit none
private
public :: my_numeric_type
type, abstract :: my_numeric_type
contains
private
procedure(op2), deferred :: add
procedure(op2), deferred :: subtract
generic, public :: operator(+) => add
generic, public :: operator(-) => subtract
end type my_numeric_type
abstract interface
function op2(a, b) result(r)
import :: my_numeric_type
class(my_numeric_type), intent(in) :: a, b
class(my_numeric_type), allocatable :: r
end function op2
end interface
end module test1
module test2
use test1, only: my_numeric_type
implicit none
type, extends(my_numeric_type) :: my_integer
private
integer :: value
contains
private
procedure, public :: add => add_my_integer
procedure, public :: subtract => subtract_my_integer
end type my_integer
contains
function add_my_integer(a, b) result(r)
class(my_integer), intent(in) :: a
class(my_numeric_type), intent(in) :: b
class(my_numeric_type), allocatable :: r
! DO SOME ADDITION.
end function add_my_integer
function subtract_my_integer(a, b) result(r)
class(my_integer), intent(in) :: a
class(my_numeric_type), intent(in) :: b
class(my_numeric_type), allocatable :: r
! DO SOME SUBTRACTION.
end function subtract_my_integer
end module test2
在本例中,子代派生类型my_integer是非抽象类型,并继承延迟绑定,因此必须重写过程(加法和减法)。但是这些过程是在my_numeric_类型中定义的私有过程,也就是说,它们不能在模块test1之外被重写,因此上面的my_integer类型无效。我该怎么办?摘自fortran 2018标准草案第7.5.5节第9段: 公共类型绑定过程可以通过该类型的任何可访问对象进行访问。私有类型绑定过程只能在包含类型定义的模块及其子代中访问 这意味着可以实现
private
延迟的
过程,但前提是所实现的过程与延迟的过程在同一模块中声明
例如:
module m
implicit none
type, abstract :: Parent
contains
procedure(add_Parent), deferred, private :: add
generic, public :: operator(+) => add
end type
abstract interface
function add_Parent(lhs,rhs) result(output)
import :: Parent
class(Parent), intent(in) :: lhs
class(Parent), intent(in) :: rhs
class(Parent), allocatable :: output
end function
end interface
type, extends(Parent) :: Child
integer :: contents
contains
procedure, private :: add => add_Child
end type
contains
function add_Child(lhs,rhs) result(output)
class(Child), intent(in) :: lhs
class(Parent), intent(in) :: rhs
class(Parent), allocatable :: output
select type(rhs); type is(Child)
output = Child(lhs%contents+rhs%contents)
end select
end function
end module
program p
use m
type(Child) :: a,b
class(Parent), allocatable :: c
a = Child(3)
b = Child(5)
c = a+b
select type(c); type is(Child)
write(*,*) c%contents
end select
end program
此约束(父级和子级必须在同一模块中声明)可能会导致大文件,并可能导致依赖项排序问题。有几种方法可以改善这种情况:
- 使用
分解模块。e、 g.子模块
可以有自己的子模块,每个父级
可以有自己的子模块子级
- 不要使用
deferred procedures,而应使用应被视为private的延迟过程的命名约定,例如尾随下划线(因此private
和add\u Parent\u
)add\u Child\u