Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop fortran 2003中的运行时多态性_Oop_Polymorphism_Fortran - Fatal编程技术网

Oop fortran 2003中的运行时多态性

Oop fortran 2003中的运行时多态性,oop,polymorphism,fortran,Oop,Polymorphism,Fortran,我正在用Fortran 2003编写一些代码,用稀疏矩阵做很多线性代数。我试图利用新标准的一些更抽象的特性,这样我就有了更简单的程序,而没有太多重复的代码 我有一个程序solver,它接受一个矩阵、一些向量、所用迭代方法的容差等。我将一个指向名为matvec的程序的指针传递给它matvec是我们用于矩阵向量乘法的子例程 问题是,有时matvec是一个过程,它在发送到此过程的常规参数之上,接收额外的参数colorlist、color1、color2。我可以想出几种方法来处理这个问题 第一个想法:定

我正在用Fortran 2003编写一些代码,用稀疏矩阵做很多线性代数。我试图利用新标准的一些更抽象的特性,这样我就有了更简单的程序,而没有太多重复的代码

我有一个程序
solver
,它接受一个矩阵、一些向量、所用迭代方法的容差等。我将一个指向名为
matvec
的程序的指针传递给它
matvec
是我们用于矩阵向量乘法的子例程

问题是,有时
matvec
是一个过程,它在发送到此过程的常规参数之上,接收额外的参数
colorlist、color1、color2
。我可以想出几种方法来处理这个问题

第一个想法:定义两个不同的抽象接口
matvec1
matvec2
和两个不同的解算器。这是可行的,但它意味着复制一些代码,这正是我试图避免的

另一个想法是:保持相同的抽象接口
matvec
,并使额外的参数
colorlist
color1
color2
可选。这意味着在每一个matvec例程中使它们成为可选的——即使它们不是真正可选的,或者对于它们根本不被使用的例程也是如此。如果我这样做,我肯定会下地狱


我可以想出很多其他的非最佳解决方案。我想了解一下这方面的一些信息——我确信有一种优雅的方法可以做到这一点,我只是不确定它是什么。

问题是,是否每次调用过程时都必须传递额外的参数(因为它们在两次调用之间发生变化),或者可以在某个点初始化它们,然后在函数中使用它们。在后一种情况下,您可以创建一个具有抽象接口的类,该接口使用基本参数定义子例程
matvec
。然后,您可以使用更专门的类来扩展该类,这些类可以容纳所需的其他选项。它们仍然必须将相同的
matvec
接口定义为父类(具有相同的参数列表),但在调用它们的
matvec
过程时,它们可以使用存储在其中的附加值


您可以找到一个类似情况的详细示例(查找显示
模块RecherAcine
的第二个示例)。

您可以将各种
matvec
例程放在通用接口后面,而不是将过程指针作为显式参数传递:

interface matvec
  module procedure matvec1, matvec2
end interface
然后,您的
解算器
例程可以只使用通用名称,包括或不包括额外参数。当使用Bálint建议的方法将
解算器
定义为具有类型绑定过程的派生类型时,当然也可以采用相同的方法:

type :: solver
  real, allocatable :: matrix(:,:), v1(:), v2(:)
contains
  procedure, pass :: matvec1
  procedure, pass :: matvec2
  generic :: matvec => matvec1, matvec2
end type
主要区别在于,这并不是使用多态性来确定要调用的正确过程,而是使用伪参数的特征

我不确定您对过程指针的意图;如果您希望在运行时更改其目标(或者可能为其“未定义”状态指定一些特殊含义),那么指针是唯一的方法,所有目标都需要匹配相同的抽象接口。如果您只需要根据它们的参数选择几个过程中的一个,那么您可以利用接口(我的示例)或重载(Bálint的示例)。类型的每个扩展都可以使用新过程扩展继承的
泛型
绑定,或者重载继承的特定绑定