下午我一直在尝试解决这个问题,但一直没有头绪,希望有人能够帮助我。
我有一个抽象基类,叫做 base_model
(例如),在Fortran2003中看起来像是:
type, abstract :: base_model
contains
procedure(initMe), pass(this), deferred :: init ! constructor
procedure(delMe), pass(this), deferred :: delete ! destructor
procedure(solveMe), pass(this), deferred :: solve
end type base_model
这里,显然使用了抽象接口块定义了 initMe
, delMe
和 solveMe
三个抽象过程。接下来我有三个派生类,分别叫做 model1
, model2
和 model3
(假设):
type, extends(base_model) :: model1
double precision :: x,y
contains
procedure :: init => init_model1
procedure :: delete => delete_model1
procedure :: solve => solve_model1
end type model1
type, extends(base_model) :: model2
contains
procedure :: init => init_model2
procedure :: delete => delete_model2
procedure :: solve => solve_model2
end type model2
type, extends(base_model) :: model3
contains
procedure :: init => init_model3
procedure :: delete => delete_model3
procedure :: solve => solve_model3
end type model3
我随后有一个“控制”对象,称为
control
(假设),它扩展了一个抽象的base_control
对象:type, abstract :: base_control
class(base_model), allocatable :: m1
class(base_model), allocatable :: m2
class(base_model), allocatable :: m3
contains
procedure(initMe), pass(self), deferred :: init
procedure(delMe), pass(self), deferred :: delete
procedure(runMe), pass(self), deferred :: run
end type base_control
type, extends(base_control) :: control
contains
procedure :: init => init_control
procedure :: delete => delete_control
procedure :: run => run_control
end type control
对象m1、m2和m3可以分配到任何模型中:model1、model2或model3,并且根据用户请求的“控制”,以任意特定顺序“解决”。
这三个可分配对象(m1、m2和m3)需要彼此传递数据。考虑到它们是“控制”对象的成员,我可以为每个模型定义一个“getter”,然后将所需数据传递到每个模型中。但是,具体的模型在编译时是未知的,因此,“控制”对象不知道要获取什么数据,实际上,模型也不知道要接收什么数据!
例如,如果我分配model1::m1(即将m1分配为model1类型),则它将包含两个数据位double precision :: x,y。然后,如果将m2分配为model2(allocate(model2::m2)),它可能需要x,但是如果将其分配为model3(allocate(model3::m2)),则它可能需要从m1获取y。因此,鉴于“控制”对象无法知道m2分配的类型,如何从m1获取必要的数据以传递到m2中?
另一个复杂之处在于模型之间的交互通常是循环的。也就是说,m1需要从m2获取数据,m2需要从m1获取数据等等。而且,所需的数据通常不仅特定于模型,而且类型和数量也是可变的。
不幸的是,数据x和y不是base_model的成员,因此将m1作为参数传递给m2也行不通。
因此,我有以下问题:
有没有更好的设计方式,使得这些对象之间可以轻松地传递数据?在这里查看后,有一些建议是重新设计对象,使它们之间的交互不是循环引用。然而,在这里那种设计是必要的!
我需要为每一个可能在对象之间共享的数据编写一个"getter"吗?这似乎需要写很多代码(我有很多可能会被共享的数据)。但是,这也似乎相当复杂,因为"getter"(特定于某个数据)还必须满足抽象接口。
在像Python这样的高级语言中,这很容易,因为我们可以简单地创建一个新的数据类型作为模型的组合,但据我所知,在Fortran中这是不可能的。
提前感谢您的帮助,非常感谢。
Edit: 经与francescalus讨论后,select type
是一个选项。确实,在上面给出的简单示例中,select type
是一个很好的选择。然而,在我的实际代码中,这将导致大量嵌套的select type
,因此如果有一种不使用select type
的方法,我更喜欢它。感谢francescalus指出我关于select type
的错误。
m2
的动态类型和组件是自由可访问的。(我可能没有跟上您的思路;即使是显示所需内容的“错误”代码也更容易解析。) - francescalus